多态
因为多态是一种类与类之间的关系性质所以多态是有使用条件的,多态的前提条件就是这些类之间一定要有继承或者实现,二选其一,这些类必须有相互关联,相互共同的属性.
多态中的成员方法
当一些类中的共同方法被抽取到一个父类或者一个父接口, 或者一些类同时继承了一个父类,或者同时实现了一个父接口,重写了这个方法,这些类之间就有了多态性质,多态提供了两种抓取信息的方式,向上转型和向下转型.
向上转型 父类类型 变量名=new 子类类型(); 本质是 抓取到在子类的对象中的父类对象, 这种行为只能使用子类中父类的方法和子类中重写了父类中的方法,如果出现重名,会先调取使用子类中重写的方法,这就是向上转型的本质 定义:当一个父类类型的变量名指向了子类类型的对象地址,这个动作就称为向上转型
向下转型 在向上转型之后因为抓取的是子类对象中自动创建的父类对象,所以无法使用子类中独有的方法,那么如果我们需要使用独有的方法,需要进行向下转型,即: 子类类型 变量名=(子类类型) 变量名(向上转型时被赋予了子类对象内存地址的变量名) ; 以此来还原为我们原本应该使用的本类对象调用即会变成: 子类类型 变量名=new 子类类型;
定义:向下转型其实就是一种强制转换类型,不过这个强制转换类型的动作是还原动作,把一个父类类型的变量中的子类对象地址重新赋值给一个子类类型的变量.
转换之间的使用:
向上转型是没有问题的,因为我们只能使用父子类之间的关系进行赋值,不是都赋不过去,但是向下转型是强制的,我们不可能把另一个类的对象强制赋给另一个类的类型变量.多态提供了一种识别判断的关键词;
instanceof 用法就是
一个被赋值了一个对象地址的变量名 instanceof 数据类型
这个关键字返回的是一个boolean类型值,如果通过就是true,不是就是false
多态的用处 ,我们可以把父类类型作为一个方法的参数(形式参数)来接收子类对象(实际参数),我们只需要使用一个方法:我们可以举一个栗子:
//定义一个抽象父类 public abstract class Animal{ //定义一个抽象方法 public abstract void eat(); } //定义子类 public class Cat extends Animal{ @Override public void eat(){ System.out.prinrln("猫吃鱼"); } } public class Dog extends Animal{ @Override public void eat(){ System.out.peintln("吃骨头"); } } public class Bird extends Animal{ @Override public void eat(){ System.out.println("鸟吃虫"); } } //定义一个测试类 public class TestDemo03{ public static void main(String[] args){ //根据不同的对象,来表现不同的吃的内容 Cat c=new Cat(); showCatEat(c);//猫吃鱼 Dog dog=mew Dog(); showDogEat(dog);//狗啃骨头 Bird bird=new Bird(); showBridEat(bird);//鸟吃虫 Cat c2=new Cat(); showAnimalEat(c2); Dog dog2=new Dog(); showAnimalEat(dog2(实际参数)); } /* public static void showCatEat(Cat cat){ cat.eat(); } public static void showDogEat(Dog dog){ dog.eat(); } public static void showBridEat(Bird bird){ bird.eat(); } }*/ /* 以上三个方法可以用多态进行优化.可以被showAnimalEat方法替代 */ public static void showAnimalEat(Animal animal(形式参数)){ animal.eat(); }
备注:如果调用多肽的方式取调用方法,不管子类有没有重写此方法,父类中一定要有,不然编译会报错.原因就是此多态对象指向的就是子类中的父类对象,并且使用形参和实参更能体现出多态的扩展性和便利性.
多态中的成员变量
有两种访问的方式:1.通过变量名来调用,等号左边是谁的类型,优先的就是谁,如果没有会继续向上找(并不会向下找喔),2. 通过成员方法来访问类中的成员变量,看这个方法在哪个类中,就会调用哪的成员变量.(向下转型之后想访问父类的东西就是this.super)