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