Java的继承多态学习总结

前言

了解继承

一般在设计继承时将共同的程序代码放在某个类中,然后告诉其他的类此类是他们的父类,当某一个类继承另一个类的时候,也就说子类继承自父类

继承例子

以动物为例设计继承关系(狮子、老虎、猫、狗、狼、犀牛)

1.找出所有共同属性和行为的对象

使用继承来放置子类中出现重复的程序代码

5个实例变量:

picture:       //动物的图片
food:           //次动物吃的食物
hunger:         //代表饥饿程度
boundaries:    //代表动物活动范围
location:       //动物在活动区域x y 坐标

4个方法:

makeNoise();//动物发出声音行为
eat();      //动物遇到食物的行为
sleep();    //动物睡眠行为
roam();     //在不吃饭不睡觉的性行为

2.设计代表共同状态或行为的类

这些对象都是动物,所以我们使用Animal作为共同的父类

Java的继承多态学习总结_第1张图片

3.决定子类是否需要让某项行为有特定不通的运行方式

观察Animal之后,eat()和makeNoise()应该由各个子类去自行覆盖实现

Java的继承多态学习总结_第2张图片

同理可以在Animal的子类中再次抽象出次父类(就是爷爷爸爸孙子关系)

4.完成类的继承层次


题外话

1、java虚拟机从继承关系树形图最下方开始搜索该方法,如果没有找到会发生什么

答:编译器会保证引用特定的方法是一定能够被调用到的,但是在执行它不会在乎该方法实际上从哪个类中找到的。比如Wolf类,编译器会检测sleep()方法,但是却不管sleep()实际上是定义在Animal这个类。如果某一个类继承了一个方法,它就会有哪个方法,方法在哪定义对于编译器来说不重要,但是在执行期,java虚拟机就是有办法找到正确的,这个正确的意思是最基接近该类型的版本。

2、如何知道继承设计是对的还是错的

答:IS-A 来判断继承关系是否正常

3、如果父类想使用子类的方法时该怎么办

答:父类不一定知道它的子类,继承的方向是不可能反过来的。

4、在子类中还打算引用父类的方法然后再加上额外的行为应该怎么办

答:可以在父类中设计出所有子类都适用的功能,让子类可以不用完全覆盖掉父类的功能,只是再加上额外的行为,可以通过super关键字来调用父类的方法

5、如何知道子类能够继承下来那些东西

答:子类可以继承父类的成员,这包括实例变量和方法,父类可以通过存取权限决定子类是否可以继承某些特定的成员。private、default、protected、public 存取权限控制谁可以接触什么。public类型的成员会被继承,private类型的成员不会被继承

5、继承有什么意义

答:通过提取一些类间共同的抽象性,能够排除掉重复的代码从而将这个部分放在父类中,如果有共同的部分需要改变,就只会有一个地方需要修改而已,且这样的改变只会应用到所有继承此行为的类,修改之后只需要重新编译就行,不需要动子类。

6、设计子类是否有层次限制,最多能够设计几层

答:java api中大多数继承的层次有深度,但是不会很深,大部分不会超过一层或两层,但是也有例外,目前并没有层次限制

7、任何一个雷都可以被继承吗,就像类的成员一样如果色红孩子为私有的就不能被继承

答:除了内部类外部类之外没有私有类的概念,有三种方法可以放置某个类被继承

第一:存取控制,类不能标记私有,但是可以不标记共有
,肥共有的类只能被同一个包的类做子类

第二:使用final关键字修改时,表示他是继承树的末端,不能被继承

第三:然该类只拥有private的构造程序

8、只使用final去表示方法而不是整个类

答:如果放置特定的方法被覆盖,可以将该方法标识上final,将这个类标识为final,表示没有任何的方法可以被覆盖


继承的要点

1、子类是extends父类出来的

2、子类会继承父类所有public类型的实例变量和方法,但是不会继承父类所有private类型的变量和方法

3、继承下来的方法可以被覆盖掉,但是实例变量不能被覆盖掉

4、使用IS-A测试来验证继承结构的合理性

5、IS-A是单方向的,比如狗是动物,但是动物不一定是狗

6、当某个方法在子类中被覆盖过,调用这个方法时会调用覆盖过的版本

7、如果Y是extends类X,且类Y是类Z的父类,则Z应该能通过IS-A X的测试


继承延伸至多态

1.继承看可以确保某个父类型之下的所有类都会有父类型所持有的全部方法

可以通过继承来定义相关类之间的共同协议,当父类中定义方法时,他们会被子类继承,这样就是对其他程序代码声明我所有的子类都能用这些方法来执行这几项工作。

比如Animal这个类模拟的所有动物的协议就是,可以makeNoise(),eat(),sleep(),roam()。

通过声明父型类型的对象引用它的子型的对象。

2.多态如何运行

1、对象声明、创建与赋值的三个步骤:

1.声明一个引用变量 Dog myDog;
    要求java虚拟机分配空间给引用变量,并将此变量命名为myDog
    此变量永远被固定钉为Dog型
2.创建对象 new Dog()
    要求java虚拟机分配堆空间给新建的Dog对象
3.连接对象和引用 =
    将新建的Dog赋值给myDog这个引用

2、引用类型与对象的类型必须相符

1.两者都是相同的类型,引用变量类型都是Dog
2.多态下引用于对象可以是不同的类型
    Animal myDog = new Dog()
3.在运用多态时,引用类型可以是实际对象类型的父类。

当你声明一个引用变量是,任何对该引用变量类型可以通过IS-A从厕所的对象都可以被赋值给该引用。也就说任何extends过声明引用变量类型的对象都可以被赋值给这个引用变量。

父类的引用可以指向子类的实例

例如:

    Animal[] animals = new Animal[5] //声明Animal数组
    //可以给该数组中放置任何animal子类的对象进入
    animals[0] = new Dog();
    animals[1] = new Cat()
    for (int i = 0; i < animals.length; i++){
        //i = 0 时调用dog的eat()
        animals[i].eat();
        //i = 1 时调用cat的roam()
        animals[i].roam();
    }

3、参数和返回类型也可以多态

如果声明一个父类的引用变量,比如Animal,并赋予子类对象给它

    class Vet{
        //参数可以为任何Animal的类型对象,执行makeNoise()的时候
        //不管它引用的对象是啥,该对象都会执行makeNoise()
        public void giveShot(Animal animal){
            animal.makeNoise();
        }
    }
    
    Class PetOwner{
        public void start(){
            Vet vet = new Vet();
            Dog dog = new Dog();
            Hippo hippo = new Hippo();
            //会执行dog的makeNoise()
            v.giveShot(dog);
            //会执行Hippo的makeNoise()
            v.giveShot(hippo);
        }
    }

覆盖的规则

1.参数必须一样,并且返回类型必须要兼容

2.不能降低方法的存取权限

也就说存取权限只能相同或者更开放

方法的重载 overload

重载的意义是两个方法名称相同但是参数不同,所以重载与多态毫无意义

1.返回类型不同

2.不能只改变返回类型

只有返回类型不同但是参数一样,这个编译器是不会允许的

3.可以更改存取权限


具体可以关注微信公众号:脑卡的葡萄干。因为我还不知道怎么把微信公众号的图片放上去的哈哈哈哈

你可能感兴趣的:(java)