2020年8月21日 多态、重载、重写的练习题

package com.atguigu.homework.test01;

/*

 * 考核点:多态,重载,重写
 * 1、分析每个类都有什么方法
 * A类:
 * public String show(D obj)
 * public String show(A obj)
 * B类:
 * public String show(D obj)
 * public String show(A obj)重写
 * public String show(B obj)
 * C类和D类,因为这里没有用它们的对象去调用方法,暂时不分析。
 * 
 * 2、继承关系
 * C-->B-->A
 * D-->B-->A
 * 
 * 3、如果出现重载的多个方法,会找其中类型最合适的
 * 
 * 4、分析代码
 * (1)a1.show(b),因为这里a1没有多态引用,编译时类型和运行时类型都是A类,只看A类的方法。
 * 此时b对象是B类型,那么public String show(A obj)这个方法最合适,因为b不能赋值给D子类的形参,只能自动向上转型为A类
   *
 * (2)a2.show(d),因为这里a2有多态编译时类型是从A类型中寻找最合适的方法,运行时执行的B类的重写的方法,如果B类没有重写,还是执行的是A类的
 * 此时d对象是D类型,在A类中public String show(D obj)这个方法最合适。
 * 
 * (3)b.show(c),因为b没有多态编译时类型和运行时类型都是B类,从B类中选择最合适的方法
 * 此时c对象是C类型,在B类中public String show(B obj)最合适的,因为C与B最近,比与A近
 * 
 * (4)b.show(d),因为b没有多态编译时类型和运行时类型都是B类,从B类中选择最合适的方法
 * 此时d对象是D类型,在B类中public String show(D obj)最合适
   */
   public class Test01 {
   public static void main(String[] args) {
       A a1 = new A();
       A a2 = new B();
       B b = new B();
       C c = new C();
       D d = new D();
       System.out.println("(1)" + a1.show(b));//A and A
       System.out.println("(2)" + a2.show(d));//A and D
       System.out.println("(3)" + b.show(c));//B and B
       System.out.println("(4)" + b.show(d));//A and D
   }
   }
   class A{
   public String show(D obj){
       return ("A and D");
   }
   public String show(A obj){
       return "A and A";
   }
   }
   class B extends A{
   public String show(B obj){
       return "B and B";
   }
   public String show(A obj){
       return "B and A";
   }
   }
   class C extends B{

}
class D extends B{
    
}
考核知识点:属性与多态无关

public
class Exam2 { public static void main(String[] args) { Base b = new Sub(); System.out.println(b.x); } } class Base{ int x = 1; } class Sub extends Base{ int x = 2; }//运行结果:1
知识点:Object类的方法

案例:

​    1、声明三角形类,包含a,b,c三边

​    (1)属性私有化,提供无参,有参构造,提供get/set

​    (2)重写:toString()

​    (3)重写:hashCode和equals方法

​    (4)编写  public double getArea():求面积方法

​    (5)编写 public double getPiremeter():求周长方法

​    2、声明测试类,在测试类中创建两个三角形对象,调用以上方法进行测试
class Triangle{
    private double a;
    private double b;
    private double c;
    public Triangle(double a, double b, double c) {
        super();
        this.a = a;
        this.b = b;
        this.c = c;
    }
    public Triangle() {
        super();
    }
    public double getA() {
        return a;
    }
    public void setA(double a) {
        this.a = a;
    }
    public double getB() {
        return b;
    }
    public void setB(double b) {
        this.b = b;
    }
    public double getC() {
        return c;
    }
    public void setC(double c) {
        this.c = c;
    }
    @Override
    public String toString() {
        return "Triangle [a=" + a + ", b=" + b + ", c=" + c + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        long temp;
        temp = Double.doubleToLongBits(a);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(b);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(c);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        //比较当前对象this和指定对象obj的地址值,如果地址值相同,就直接返回true,后面就不看了
        if (this == obj)
            return true;
//如果obj是null,说明是空对象
    //因为当前对象this一定是非空,因为如果为空的话,早就报空指针异常了
    //非空对象与空对象equals,一定是false
    if (obj == null)
        return false;
    
    //获取当前对象的运行时类型,和obj对象的运行时类型,看是否一致,如果不一致,就直接返回
    if (getClass() != obj.getClass())
        return false;
    
    //把obj对象向下转型
    //这里没有对obj进行instanceof判断是因为上面确定了this和obj都是三角形类型的对象
    //为什么要强制?因为obj编译时类型是Object类型,是无法调用obj.a、obj.b、obj.c等
    Triangle other = (Triangle) obj;
    //if(a == other.a),为什么不这么写,因为double类型是不精确的
    //Double.doubleToLongBits(a)把double类型的值转为二进制形式进行比较,相对更精确
    if (Double.doubleToLongBits(a) != Double.doubleToLongBits(other.a))
        return false;
    if (Double.doubleToLongBits(b) != Double.doubleToLongBits(other.b))
        return false;
    if (Double.doubleToLongBits(c) != Double.doubleToLongBits(other.c))
        return false;
    return true;
}
public double getArea(){
    double p = (a + b + c)/2;
    return Math.sqrt(p *(p-a) * (p-b) * (p-c));
}
public double getPiremeter(){
    return a + b + c;
}

 

posted @ 2020-08-21 16:16  窦云鹏  阅读(264)  评论(0编辑  收藏  举报