目录
1.Person p = new Student()是什么意思?
2.判断两个类之间是否存在父子关系,就用instanceof关键字。
3.为什么System.out.println(b instanceof String); 编译的时候就要报错呢?
1.Person p = new Student()是什么意思?
Student t = new Student();
实例化一个Student的对象,这个不难理解。但当这样定义时:
Person p = new Student();
这句代码的意思是:我们创建了一个名为 p 的对象,这个对象的类型是 Person,但是它实际是一个 Student 类型的对象。可以想象成 Person 是一个大类,而 Student 是这个大类下面的一个具体的子类。(如:小明往小了说他是个学生,往大了说他是个人。)
在这段代码中,new Student() 是在创建一个新的学生对象。虽然 p 被声明为 Person 类型,但它实际上是一个 Student 类型的实例。这样做的好处是可以利用 Person 类型的属性和方法,同时也可以使用 Student 类中定义的特殊属性和方法。简单来说,就是你可以把一个具体的学生当作一个更一般的人的概念来使用。
2.判断两个类之间是否存在父子关系,就用instanceof关键字。
实例代码:创建三个类,Person、Teacher、Student。Person都是Teacher和Student的父类:
(1)创建了一个名为 a 的对象,这个对象的类型是 Object,但是它实际是一个 Student 类型的对象。判断对象a是否是以下这些类或者其子类的对象:
a实际是Student类的对象(true);a是Person类中子类Student的对象(true);a是Object类中子类Student的对象(true);a既不是Teacher类的对象,也不是Teacher子类的对象(false);a既不是String类的对象,也不是String子类的对象(false)。
(2)创建了一个名为 b 的对象,这个对象的类型是 Person,但是它实际是一个 Student 类型的对象。判断对象b是否是以下这些类或者其子类的对象:
b实际是Student类的对象(true);b是Person类中子类Student的对象(true);b是Object类中子类Student的对象(true);b既不是Teacher类的对象,也不是Teacher子类的对象(false);不管把b看成是Person类还是Student类,都与String类没有继承关系,编译报错。
(3)创建了一个名为 c 的对象,这个对象的类型是Student,但是它实际也是一个Student 类型的对象。判断对象c否是以下这些类或者其子类的对象:
c实际是Student类的对象(true);c是Person类中子类Student的对象(true);c是Object类中子类Student的对象(true);c是Student类,与Teacher类没有继承关系,编译报错;c是Student类,与String类没有继承关系,编译报错。
3.为什么System.out.println(b instanceof String); 编译的时候就要报错呢?
记住一句话:编译看左,运行看右。
指创建对象的这句代码 如:Person b = new Student(); 左边是父类(Person)、右边是子类(Student)。
(1)编译的时候:把对象b往大了看,看成左边的父类(Person),如果父类都与相比较的类型(String)没有关系的话,子类更不没关系了。因此报错!
(2)运行的时候:把对象b往小了看,看成右边子类(Student)的对象,再与B比较看是否具有继承关系。
(3)公式:a instanceof B
a的大类型(父类)至少要与B是继承关系才能比较,要不然会编译报错!
4.类型转化
父类是高类型,子类是低类型;低转高,自动转换;高转低,强制转换。
举例:Person类创建一个run方法,Student类创建一个go方法:
(1)父类转子类
创建了一个名为 a 的对象,这个对象的类型是Person,但是它实际是一个Student 类型的对象。编译看左,所以这里把a看作是Person类型的,因此无法调用Student类独有的go方法,需要将a强制转换为Student类型(高转低,强制转),再赋值给Student类型的a1,最后用a1调用go方法。也可以直接用一句代码搞定:((Student)a).go();
(2)子类转父类
创建了一个名为 b的对象,这个对象的大类和小类都是Student 类型。编译看左, a是Student类型,可以调用Student类独有的go方法。Person b1 = b;自动把b转化为Person类型的b1,这时b1就无法调用Student类独有的go方法了。
结论:子类转换为父类,可能丢失自己独有的一些方法!
5.总结
(1)父类的引用指向子类对象 如:Person a = new Student();
(2)子类转父类,向上转型,自动转,但会丢失子类独有的方法
(3)父类转子类,向下转型,强制转
(4)方便方法的调用,减少重复的代码!简洁