态的学习例题,用于理解多态的应用。
通常来说,在一个类中定义的属性和方法被其他类继承或重写后,当把子类对象直接赋值给父类引用变量是,相同类型的变量调用同一个方法讲呈现不同形态。通过多态,消除减小了类与类之间的耦合度,就是依靠行,大大提高了程序的可扩展性和可维护性。
父类Animal 子类Cat
子类对象当做父类类型使用的情况,就叫做向上转型。
Animal an1=new Cat();
//new Cat()返回一个对象,即一个地址 ,这个地址就是对象所在的地址。其对象的本质是Cat类型。
//an1是父类的一个引用,是一个引用数据类型,其储存这Cat对象的地址。
如果Cat类没有重新父类的已存在方法,在an1调用该方法是将执行父类的方法。
注:
如果父类的方法是用static 修饰的,就算子类重写了,但也不会调用子类的方法。(就像该方法已经被限定了,改变不了了)
————————————————————
下面是一个实例,宠物主任喂养不同的宠物时,反应出不同的表现。
一开始主任喂养了一直小猫和小狗,通过喂养猫或狗来获得快乐,如果主任想要在养一只宠物要怎么办呢?
import java.util.*;
//主人类
class Marst {
//主人喂养宠物
public void feed(Pet pet) {
//Pet pet=new XX();
//pet父类引用指向子类对象
//引用类似C语言指针
pet.eat();
}
//主人训练宠物技能
public void skill(Pet pet) {
//如果pet父类引用的子类是Cat类,则转型
//因为父类引用无非调用子类特有方法
if(pet instanceof Cat) {
Cat cat=(Cat)pet;
//向下转型
cat.cathMouse();
}
//判断是否是Dog类
if(pet instanceof Dog) {
Dog dog=(Dog)pet;
dog.kanJia();
}
}
}
//抽象宠物类
abstract class Pet {
//宠物的行为吃食物
abstract public void eat();
}
//不抽象
class Animal {
public void feed(Pet a) {
a.eat();
}
}
//宠物//猫class Cat extends Pet {
void eat() {
System.out.println("喵喵喵");
}
//小猫的特有行为方法
public void cathMouse() {
System.out.println("小猫抓老鼠");
}
}
//狗
class Dog extends Pet {
public void eat() {
System.out.println("汪汪汪");
}
//小狗的行为
public void kanJia() {
System.out.println("小狗看家");
}
}
public class HelloWorld {
public static void main(String[] args) {
Marst marst=new Marst();//主人对象
//Cat cat=new Cat();
//猫对象a
marst.feed(new Cat());
//这样也可以
//Dog dog=new Dog();
marst.feed(new Dog());//可以传入对象
//当有新宠物时直接创建类继承Pet就行
//通过多态而不改变主人类,代码扩展性提高
marst.skill(new Cat()) ;
}
}
多态是类的继承,方法重写,以及父类引用指向子类对象而实现的。
- 多态不能使用子类特有的成员行为方法。
- 如果调用子类特有的方法是需要向下转型。
对象的类型转换用instanceof检测
如果 对象1的本质 instanceof(是) 对象2
,这需要向下转型。
向下转型利用强制转换实现
要转的对象类型 对象名 =(和前面的一致)原来的对象类型
注:
在进行对象的向下转换时,必须转换为本质类型,否则转换时会出现错误。