面向对象三大特性:封装、继承、多态。
一、java 多态
生活中,不同人物角色看待同一个对象的视角不同,关注点也不相同。

java中的多态
概念:父类引用指向子类对象,从而产生多种形态。

多态是一个实际上是一个小转大的过程。在java中小转大是欢迎的,例如double类型可以接收int型
Dog是继承于Animal,逻辑上狗是属于动物类,所以Dog可以转成Animal
在一个新接触的东西中,在对象里能调用的,我们一般只需要弄懂它对构造方法、属性和方法、继承的影响就行了
(可能开始时候不理解多态的用意,实际上在后续学习中会经常遇到,就会有不同的理解了)
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
}
}
class Animal{}
class Dog extends Animal{}1.1多态的构造方法
如果是多态,实例化出来的构造方法是先怎样运行的呢?
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
}
}
class Animal{
public Animal(){
System.out.println("我是动物构造方法");
}
}
class Dog extends Animal{
public Dog(){
System.out.println("我是狗狗的构造方法");
}
}
运行结果:
我是动物构造方法
我是狗狗的构造方法可以看到,他是先调用父类的构造方法,再调用子类的构造方法,子类父类的关系没有任何改变
1.2多态的方法与属性
那么接下来添加方法和属性
在这里,我会一只用Animal和Dog例子来说,我们可以在着多态中,将狗对象,当成动物来看待
方法
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
}
}
class Animal{
public void eat(){
System.out.println("动物要吃");
}
}
class Dog extends Animal{
@Override //重写动物eat方法
public void eat() {
System.out.println("狗狗要吃");
}
}
结果:
狗狗要吃这个也正常,属于正常的继承关系。
那么如果Dog类对象里有Animal没有的方法呢?
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
animal.run(); //报错
}
}
class Animal{
public void eat(){
System.out.println("动物要吃");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗狗要吃");
}
public void run(){
System.out.println("狗狗要跑");
}
}
结果:
报错:Cannot resolve method 'run()'
找不到run方法在多态里,我们只能调用父类有的方法,而不能调用子类独有的方法。
属性
属性是否也像上面的例子一样,只能调用父类有的属性,不能调用子类独有有的属性呢?
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
//调用属性
System.out.println(animal.breed);
System.out.println(animal.age);
}
}
class Animal{
public String breed = "动物";
public int age = 18;
}
class Dog extends Animal{
public String breed = "狗";
public int age = 8;
}
结果:
动物
18Dog:震惊!我调用属性的结果,既然是用Animal(父类)的!!
多态里,我用的方法是自己的,用的属性是父类的(这原因是Java编译的静态动态问题,只知道结果就好了)
那么我们方法中调用的值是父类的还是子类的?
public class Demo01 {
public static void main(String[] args) {
Animal animal = new Dog();
animal.method();
}
}
class Animal{
public String breed = "动物";
public int age = 18;
public void method(){
System.out.println("我是" + breed + ",今年:"+age + "岁");
}
}
class Dog extends Animal{
public String breed = "狗";
public int age = 8;
@Override
public void method() {
System.out.println("我是" + breed + ",今年:"+age+"岁");
}
}
结果:
我是狗,今年:8岁可以看到在方法里调用属性是自己的属性,不是父类的属性。
Dog: 还好我自己方法里调用的属性是自己的,不然我两也太乱了。
Animal:但是如果你不重写我的method方法,直接调用,是调用我的属性值的
Dog:这不是正常的继承关系是这样的吗?我继承了你,但我没有重写方法,所以调用的是你的方法啊… …
Animal:正常个屁,无论是否多态实例化的, 你懒得写,调用的方法甚至里的属性都是用我的
Dog:大家都用你不好吗,谁叫你是老大
在不重写的前提下,我们对比一下正常的实例化和多态的实例化
public class Demo01 {
public static void main(String[] args) {
//多态的
Animal animal = new Dog();
animal.method();
//正常实例化的
Dog dog = new Dog();
dog.method();
}
}
class Animal{
public String breed = "动物";
public int age = 18;
public void method(){
System.out.println("我是" + breed + ",今年:"+age);
}
}
class Dog extends Animal{
public String breed = "狗";
public int age = 8;
}
结果:
我是动物,今年:18
我是动物,今年:18可以看到,多态实例化的和普通实例化的结果一样
子类独有的属性多态中可以用吗?
public class Demo01 {
public static void main(String[] args) {
//多态的
Animal animal = new Dog();
System.out.println(animal.hobby); //报错
}
}
class Animal{
public String breed = "动物";
public int age = 18;
}
class Dog extends Animal{
public String breed = "狗";
public int age = 8;
public String hobby = "eat"; //多个这个属性
}
结果:
报错,Cannot resolve symbol 'hobby'
找不到hobby属性和方法一样,多态只能调用的是父类有的属性,自己独有的不能调用
Animal:你想模仿我,就要按着我的模板来,我有什么你就有什么,但你有独有的就不能用,像什么hobby = “eat”,我可不像你一样就知道吃。
Dog:别说了…
Animal:在多态里,你不能用自己的属性和方法来,这是你品种的特征和行为,不是我的,也别和我扯上
二 、装箱、拆箱
装箱就是小转大,拆箱就是大转小(强转)
- 向上转型,子类转成父类 由小转成大
Animal animal = new Dog();- 向下转型,父类转成子类 由大转成小
Animal animal = new Dog();
Dog dog = (Dog)animal;------------强行转换
三、instanceof关键字
向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。
语法:父类引用 instanceof 类型 //返回boolean类型结果

多态的典型例子
public class Demo01 {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
animalEat(dog);
animalEat(cat);
}
public static void animalEat(Animal animal){
if(animal instanceof Cat){
((Cat) animal).catEat(); //--------------->强转
}else if(animal instanceof Dog){
((Dog) animal).dogEat(); //--------------->强转
}
}
}
class Animal{
}
class Cat extends Animal{
public void catEat(){
System.out.println("猫吃吃");
}
}
class Dog extends Animal{
public void dogEat(){
System.out.println("狗吃吃");
}
}
结果:
狗吃吃
猫吃吃在这里,我们有时候需要把一个类作为参数,如果没有多态,我们就需要创建两个 animalEat()方法,如果我需要更多的类呢,那不是需要创建更多的对应方法?
所以多态可以说是极大便利了我们的代码,是java类里面比较抽象的知识点之一,先知道怎么用,调用的结果是什么就好了。
















