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; }