多态性和instanceof关键字的使用

 

person类

package com.atguigu.java3; public class Person { String name; int age; int id= 1001; public void eat(){ System.out.println("人吃饭"); } public void walk(){ System.out.println("人走路"); } }

man类

package com.atguigu.java3; public class Man extends Person{ boolean isSmoking; int id = 1002; public void earn(){ System.out.println("男人挣钱养家"); } public void eat(){ System.out.println("男人吃肉"); } public void walk(){ System.out.println("男人霸气走路"); } }

woman类

package com.atguigu.java3; public class Women extends Man{ boolean isBeauty; public void goShopping(){ System.out.println("女人喜欢购物"); } public void eat(){ System.out.println("女人少吃减肥"); } public void walk(){ System.out.println("女人窈窕的走路"); } }

personTest类

package com.atguigu.java3; public class PersonTest { public static void main(String[] args) { Person p = new Man(); p.eat(); p.walk(); System.out.println(p.id); Man m1 = (Man)p; // Women m2 = (Women)m1; // m2.goShopping(); if(m1 instanceof Women){ Women w1 = (Women)m1; w1.goShopping(); System.out.println("**********Women************"); } if(m1 instanceof Man){ Man m2 = (Man)m1; m2.earn(); System.out.println("**********man************"); } if(m1 instanceof Person){ System.out.println("**********Person************"); } if(m1 instanceof Object){ System.out.println("**********Object************"); } } }

man和woman类都要是person类的子类,然后对person类的方法要进行重写,这是多态性的条件,然后

Person p = new Man();

new的对象不是person类的而是符合条件的子类的

此时这个对象只能调用重写父类的方法------------->虚拟方法调用

而子类特有的方法调不了

输出的结果是子类重写方法运行的结果,即编译看左边,运行看右边。

编译时看左边父类的哪些方法在子类重写过,而运行时结果看子类重写的方法。这个叫做虚拟方法调用

 

多态性的举例

//多态性的使用举例一: public class AnimalTest { public static void main(String[] args) { AnimalTest test = new AnimalTest(); test.func(new Dog());//输出狗的方法 test.func(new Cat());输出猫的方法 } public void func(Animal animal){//Animal animal = new Dog(); animal.eat(); animal.shout(); if(animal instanceof Dog){ Dog d = (Dog)animal; d.watchDoor(); } } // public void func(Dog dog){ // dog.eat(); // dog.shout(); // } // public void func(Cat cat){ // cat.eat(); // cat.shout(); // } } class Animal{ public void eat(){ System.out.println("动物:进食"); } public void shout(){ System.out.println("动物:叫"); } } class Dog extends Animal{ public void eat(){ System.out.println("狗吃骨头"); } public void shout(){ System.out.println("汪!汪!汪!"); } public void watchDoor(){ System.out.println("看门"); } } class Cat extends Animal{ public void eat(){ System.out.println("猫吃鱼"); } public void shout(){ System.out.println("喵!喵!喵!"); } }

按住Ctrl键进入方法体时

p.eat();

p.walk();

进入的是person的eat、walk方法体内,因为是person类体现的多态性,方法就是体现多态性的一个途径。

 

明确:子类可以获取父类的私有属性和方法,因为像属性的话,在父类中设置get和set方法,然后就可以调用get和set方法修改属性和调用属性。

将父类的私有方法放在一个公有方法里面,就可以通过调用共有方法来间接调用私有方法

这些私有的属性和方法都是子类对象加载父类来的,即每个子类对象在堆结构中都有父类的属性和方法,不管是共有的还是私有的,这样就体现了继承性

 

 

同时,属性是不能体现多态性的,所以,父类和子类定义了同一个属性时,调用

System.out.println(p.id);

结果是父类的属性,即1001,

,这时候,就是编译运行都看左边了

即子类定义了与父类同名的的属性,这个属性不会覆盖父类的同名属性,即编译运行都看左边

 

 

 

 

 

调用时不能调用子类特有的属性和方法,但是要明确一点,声明对象的时候,子类的那些属性都被加载进来了,只不过因为声明的person类的类型,导致那些子类特有属性和方法都被屏蔽了。但是在堆内存都有的

 

 

如何调用P3中特有的方法呢

强制将person类型装换为man类型,再赋给m1,m1就可以调用

man类型的方法和属性

向下转型有风险,有可能不成功

 

instanceof关键字的使用

明确:

if(m1 instanceof Person){ System.out.println("**********Person************"); } if(m1 instanceof Object){ System.out.println("**********Object************"); }

返回的是true

m1是person类的子类的实例

 

 

 

向下转型要想通过,有两种情况

a instanceof A

a对象是A的实例,即a是A这个类new出来的

a instanceof B

产生a对象的类是B的子类

posted @ 2021-09-06 21:05  不久  阅读(66)  评论(0)    收藏  举报