继承与多态

author author     2022-08-13     602

关键词:

规划程序之前要考虑到未来,及时做好应对需求变更的准备。

  良好的面向对象程序设计需要尽量提高程序的扩展性和灵活性,当需求变更或加入新的类型时不至于重写设计或改写太多既有代码。众所周知,继承是面向对象程序设计三大基本特性(封装、继承、多态)之一,充分理解继承的原理机制,对于书写高质量的程序至关重要。

  面向对象程序设计显著特点就是尽量少写重复代码,多考虑既有代码的重构,以此提高程序的扩展性。为什么需要继承机制?说白了就是为了减少重复代码。在设计继承时,我们总会从一系列具有相同属性和行为的类中抽象出共有的部分,然后封装在父类中,以Java方式来说,“子类继承父类”意味着子类拥有父类的实例变量和方法,这部分共有的属性和行为无需重新编写,直接继承即可;当然,子类也可以添加自己特有的实例变量和方法,利用继承机制可以大大程序设计的灵活性。

  以上叙述了这么多,但好像太理论了,完全没有体现出继承的特点和优势。别着急,考虑这样一个案例:

  “假设你需要设计一套动物仿真系统,可以使用户将一群动物丢至特定的环境,并因此模拟出不同动物的状态和行为。现已存在部分被告知的动物的属性和行为,但并不清楚以后会有多少动物被加进来。你需要设计扩展性良好的应用程序,以此应对后期动物园管理员以任意时间引进任意数量动物的需求。”

   好吧,话有点啰嗦,还是直接开始设计吧。

  (1)找出类间具有共同属性和行为的对象,并抽象出共有部分。

    假设你的动物仿真系统需要存储动物的图像(picture)、食物(food)、饥饿程度(hunger)、活动范围的长和宽(boundaries)、活动过程中的X、Y坐标(location)、另外但凡动物均有发声(makeNoise)、饮食(eat)、睡眠(Sleep)、闲逛(roam)的行为。

    假定现在的动物系统中有狮子(Lion)、老虎(Tiger)、猫咪(Cat)、河马(Hippo)、狼(Wolf)、狗(Dog)

 

 (2)抽象出代表共同状态和行为的类

    经以上分析我们抽象出动物(Animal)作为整个系统的顶层父类,并将共有的图像(picture)、食物(food)、饥饿程度(hunger)、活动范围的长和宽(boundaries)、活动过程中的X、Y坐标(location)实例变量和发声(makeNoise)、饮食(eat)、睡眠(Sleep)、闲逛(roam)方法加入Animal这个类中,并利用IDEA自动生成了Get和Set方法。

public class Animal {
    String picture;//动物图像的存储路径
    String food;//目前只有meat和grass两种
    Integer hunger;//饥饿程度
    Double boundaries;//活动区域面积
    Location location = new Location(); //活动坐标

    public void makeNoise() {//发声
        System.out.println("makeNoise method is invoked in Animal....");
    }

    public void eat() { //饮食
        System.out.println("eat method is invoked in Animal....");
    }

    public void sleep() {//睡眠
        System.out.println("sleep method is invoked in Animal....");
    }

    public void roam() { //闲逛
        System.out.println("roam method is invoked in Animal....");
    }

    public String getPicture() {
        return picture;
    }

    public void setPicture(String picture) {
        this.picture = picture;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public Integer getHunger() {
        return hunger;
    }

    public void setHunger(Integer hunger) {
        this.hunger = hunger;
    }

    public Double getBoundaries() {
        return boundaries;
    }

    public void setBoundaries(Double boundaries) {
        this.boundaries = boundaries;
    }

    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }
}

 

(3)确定子类是否需要重写方法和添加自己的实例变量

   观察Animal,容易发现每个动物的eat()方法和makeNoise()方法的方式应该不一样,当然睡眠也可以不同,但为使得描述问题的简单,我们在此假定睡眠一样。以makeNoise()为例,狗狗(Dog)的发声是“汪汪汪”、猫咪(Cat)的发声是“喵喵喵”等等。。根据实际情况,每个子类都可以重写(overload)继承自父类的方法以满足自己的需求。例如Dog子类。

public class Dog extends Animal{
    public void makeNoise() {
        System.out.println("大家好,我是旺财!,我喜欢旺旺旺...");
    }

    public void eat() {
        System.out.println("大家好,我是旺财!,我喜欢鲜美的骨头...");
    }
}

      当然其他的动物也可以根据自己的特性重写继承自父类的方法,或是添加实例变量,在此不再一一列出。

 

 (4)寻找使用共同行为的子类来构造出更多的抽象化机会

   现实世界中,动物本身具有组织化的层次(界、门、纲、目、科、属、种),据此,我们可以抽象出有意义的类。观察发现,现有动物中可以抽象出Canine(猫科)、Feline(犬科)两个科,其中狮子(Lion)、老虎(Tiger)、猫咪(Cat)属于Canine(猫科)、Hippo独立于猫科和犬科、狼(Wolf)、狗(Dog)属于Feline(犬科)。所以我们可以进一步的抽象出Canine和Feline两个类。

public class Canine extends Animal {
    public void roam() {//重写来自Animal的roam()方法
        System.out.println("roam method is invoked in Canine....");
    }
}
public class Feline extends Animal {
    public void roam() { //重写来自Animal的roam()方法
        System.out.println("roam method is invoked in Feline....");
    }
}

 

(5)完成类的继承层次

    根据以上分析,我们可以完成类的继承层次,其中Animal属于顶层父类,Canine(猫科)、Hippo(河马)、Feline(犬科)分别继承自Animal;狮子(Lion)、老虎(Tiger)、猫咪(Cat)继承Canine(猫科);狼(Wolf)、狗(Dog)继承Feline(犬科),由此可得类间继承关系图

技术分享

   至此,动物仿真系统的所有类间关系就分析整理出来了,当然,每个子类可以任意添加自己的方法或是overload继承自父类的方法,极大的减少了重复代码的书写,并且提高了系统扩展性。

 



06继承与多态

继承与多态动手动脑问题:public class ParentChildTest{public static void main(String[]args){Parentparent=new Parent();parent.printValue();Childchild=new Child();child.printValue( 查看详情

继承与多态

1.请看以下“变态”的类publicclassParentChildTest{publicstaticvoidmain(String[]args){Parentparent=newParent();parent.printValue();Childchild=newChild();child.printValue();parent=child;parent.printValue();parent. 查看详情

学习-继承与多态

  一继承  类与类的isa关系,叫做继承  关键字:extends-继承  语法:publicclass子类名extends父类名{  效果:父类所以属性行为子类自动具有;java中只有单继承,一个子类只能继承一个父类  重写:子类把来自于父类的方法覆... 查看详情

继承与多态

1.  代码: publicclassTest{publicstaticvoidmain(Stringargs[]){Ca=newC();a.display();}}classA{publicvoiddisplay(){System.out.println("hello");}}classCextendsA{publicvoiddisplay(){System.out 查看详情

继承与多态

我们可以从某个现有的class继承定义一个class,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Baseclass、Superclass)如:classDog(Animal):而不是classDog(object):好处:1.子类能获得父类的全部功能,包括父类的方法2... 查看详情

继承与多态

1.继承中类型的转换源代码:classMammal{}classDogextendsMammal{}classCatextendsMammal{}publicclassTestCast{publicstaticvoidmain(Stringargs[]){Mammalm;Dogd=newDog();Catc=newCat();m=d;d=m;d=(Dog)m;d=c;c=(Cat)m;}}这个程序 查看详情

继承与多态-课后作业

1. 继承条件下的构造方法调用classGrandparent{publicGrandparent() { System.out.println("GrandParentCreated."); }publicGrandparent(Stringstring) { System.out.println("GrandParentCreated.String:"+string); }}cla 查看详情

继承与多态(代码片段)

第三章:继承与多态知识梳理面向对象具有三大特性:封装、继承、多态本章的内容:学习Java中包的概念以及另外两大特征:继承和多态。1.包的定义与使用(1)Java中通过包来完成对类的管理,每个... 查看详情

类的继承与多态

继承//概念:子类可以继承父类的一切//方法重写:在子类里面对父类的方法进行重写//特点:单继承:一个子类只能有一个父类,一个父类可以派生出多个子类//override:重写//overload:重载,编译多态classRen{ public$name; func... 查看详情

继承与多态(代码片段)

 最近学习廖大的教程,看到类的继承与多态,看了一下做一下总结。 自雷继承父类的时候,可以继承父类里定义的函数(类里定义函数的时候一定要将第一个参数定义self,class后面紧接着是类名,即Student,类名通常是... 查看详情

第10章接口继承与多态

10.1packagetex;publicabstractclassone abstractvoidtest(); publicstaticvoidmain(Stringargs[]) newone(); //无法实例化   查看详情

继承与多态动手动脑

方法覆盖(override)”的要点classFather{publicvoidprintValue(){System.out.println("Parent.printValue()JmyValue");}}classSonextendsFather{ publicvoidprintValue(){ super.printValue();System.out.println("Child.pr 查看详情

06-继承与多态(动手动脑与验证)

一、继承条件下构造方法的调用测试代码一:1classGrandparent2{3publicGrandparent()4{5System.out.println("GrandParentCreated.");6}7publicGrandparent(Stringstring)8{9System.out.println("GrandParentCreated.String:"+string);10} 查看详情

继承与多态

 1.     观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!classGrandparent{publicGrandparent(){Syst... 查看详情

06-继承与多态

...;不能反过来,因为先有父类,再有子类,子类是从父类继承来的。packagedong;publicclassA{publicstaticvoidmain(String[]args){ //TODO自动生成的方法存根Childrenchildren=newChildren();children.Myname(); }packagedong;publicclassP 查看详情

继承与多态

...类型时不至于重写设计或改写太多既有代码。众所周知,继承是面向对象程序设计三大基本特性(封装、继承、多态)之一,充分理解继承的原理机制,对于书写高质量的程序至关重要。 面向对象程序设计显著特点就是尽量... 查看详情

多态与继承

多态:可对不同类型的对象执行相同的操作。继承:继承是一种另一种偷懒的方式,程序员总是想避免多次输入同样的代码。可以通过创建函数来达到这个目标,但现在要解决一个更微妙的问题。如果你已经有了一个类,并要创... 查看详情

继承与多态

 1.构造函数:完成对象的初始化工作 以下代码为何无法通过编译?哪儿出错了?  编译器提示:构造函数Foo()未定义 //正确代码如下publicclassTest    publicstaticvoidmain(String[]args)    &... 查看详情