一、Java继承

继承是面向对象编程中非常强大的一种机制,首先它可以复用代码,例如当大家让Student从Person继承时,Student就获得了Person的所有功能,大家只需要为Student编写新增的功能。Java使用extends关键字来实现继承:

class Person {

    private String name;

    private int age;

    public String getName() {...}

    public void setName(String name) {...}

    public int getAge() {...}

    public void setAge(int age) {...}

}

class Student extends Person {

    // 不要重复name和age字段or方法,只需要定义新增score字段/方法:

    private int score;

    public int getScore() { … }

    public void setScore(int score) { … }

}

如上所示可见,通过继承,Student只需要编写额外的功能,不再需要重复Person代码。注意到我们在定义Person的时候,没有写extends。在Java中,没有明确写extends的类,编译器会自动加上extends Object。所以,任何类,除了Object,都会继承自某个类。

二、Java:super

super关键字表示父类(超类)。子类引用父类的字段时,可以用super。但是,在某些时候,就必须使用super。大家来看一个栗子:

class Person {

    protected String name;

    protected int age;

    public Person(String name, int age) {

        this.name = name;

        this.age = age;

    }

}

class Student extends Person {

    protected int score;

    public Student(String name, int age, int score) {

        this.score = score;

    }

}

public class Main {

    public static void main(String[] args) {

        Student s = new Student("Xiao Ming", 12, 89);

    }

}

Java结果如下:

运行上面的代码,会得到一个编译错误,大致意思是在Student的构造方法中,无法调用Person的构造方法,为什么会出现这个错误呢?

这是因为在Java中,任何子类的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地显式调用父类的构造方法,若父类没有默认的构造方法,就会编译报错!因为,好的解决办法或者说良好的写法就是,子类必须显式调用super()并给出参数以便让编译器定位到父类的一个合适的构造方法。

这里还顺带引出了另一个问题:即子类不会继承任何父类的构造方法。子类默认的构造方法是编译器自动生成的,不是继承的。

正确代码如下,增加一行super():

class Person {

protected String name;

protected int age;

public Person(String name, int age) {

this.name = name;

this.age = age;

    }

}

class Student extends Person {

protected int score;

public Student(String name, int age, int score) {

super(name, age); // 增加一行,调用父类的构造方法

this.score = score;

    }

}

public class java1 {

public static void main(String[] args) {

    Student s = new Student("LiLei", 12, 89);

    System.out.print( s.name + "   " + s.age +"   "+ s.score+"    ");   

  }

}

Java结果如下:

三、Python继承

Python与C++、Java一样,也是支持面向对象(OOP)的动态语言的编程语言,因此同样具有面向对象的三大特性:封装、继承、多态。但Python又有一些极具Python自身特色的不同之处,今天微微老师就来和大家讨论一下,Python的继承、__init__初始化、super方法,也许大家之前会用,知道要这么写才能运行程序,否则会报错,但是为什么要这么写,可能想不明白,看完本文,期待能彻底搞清楚了。

大家先来看一个栗子,先写了一个父类Parent及父类的__init__构造函数,然后写了一个子类Child继承父类Parent,也写了子类的__init__构造函数:

class Parent(object):

    def __init__(self, name):

        self.name = name

        print("create an instance of:", self.__class__.__name__)

        print("name attribute is:", self.name)

#子类继承父类        

class Child(Parent):

    #子类中没有显示调用父类的初始化函数

    def __init__(self):

        print("call __init__ from Child class")

接下来,将子类Child实例化,看看效果,打印输出什么结果:

#将子类实例化  

c = Child()

Python结果如下:

如上图所示的输出结果,不难看出,我们将子类实例化并没有调用父类的构造函数,只是调用了子类的构造函数。由于在子类中没有显示调用父类的初始化函数,则父类的属性不会被初始化,因而此时调用子类中name属性会报错不存在:  AttributeError: ‘Child’ object has no attribute ‘name’

四、Python:super

当在Python中出现继承的情况时,一定要注意初始化函数_init_的行为:

1. 如果子类没有定义自己的初始化函数,父类的初始化函数会被默认调用;但是如果要实例化子类的对象,则只能传入父类的初始化函数对应的参数,否则会出错。

2. 如果子类定义了自己的初始化函数,而在子类中没有显式调用父类的初始化函数,则父类的属性不会被初始化。

3. 如果子类定义了自己的初始化函数,在子类中显式调用父类,子类和父类的属性都会被初始化。

因此,Python继承正确而良好的写法,应该是下面代码这样:

class Parent(object):

    def __init__(self, name):

        self.name = name

        print("create an instance of:", self.__class__.__name__)

        print("name attribute is:", self.name)

#子类继承父类        

class Child(Parent):

    def __init__(self):

        print("call __init__ from Child class") 

        super(Child,self).__init__("小小明")

p = Parent('小明')   

c = Child()

print(p.name)  

print(c.name)

如上面代码,子类定义了自己的初始化函数,并使用super方法显式调用父类__init__,则子类和父类的属性都会被初始化。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

热门产品

php编程基础教程.pptx|php编程培训,php,编程,基础,教程,pptx
php编程基础教程.pptx

历史上的今天:04月20日

ThinkPHP5快速入门

ThinkPHP5快速入门目 录零、序言一、基础二、URL和路由三、请求和响应四、数据库五、查询语言六、模型和关联 (1)模型定义 (2)基础操作 (3)读取器和修改器 (4)类型转换和自动完成 (5)查询范围 (6)输入和验证 (7)关联 (8)模型输出七、视图和模板八、调试和日志九、API开发十、命令行工具十一、扩展十二、杂项SessionCookie验证

ThinkPHP5快速入门基础

ThinkPHP5快速入门基础一、基础快速入门 ( 一 ) :基础本章介绍了 ThinkPHP5 .0 的安装及基本使用 ,并给出了一个最简单的示例带你了解如何开始开发 ,主要包 含 :简介官网下载 omposer安装和更新CGit下载和更新目录结构运行环境入口文件调试模式控制器视图读取数据总结在学习 ThinkPHP5.0 之前 ,如果你还不理解面向对象和命名空间的概念 ,建议首先去PHP手册恶

热门专题

易捷尔单招|易捷尔单招,易捷尔单招培训,易捷尔单招报名,易捷尔单招考试,易捷尔单招培训学校,易捷尔单招分数
易捷尔单招
卓越综合高中|卓越综合高中
卓越综合高中
开放大学|开放大学报名,开放大学报考,开放大学,什么是开放大学,开放大学学历,开放大学学费,开放大学报名条件,开放大学报名时间,开放大学学历,开放大学专业
开放大学
安徽中源管业有限公司|安徽中源管业有限公司,安徽中源管业有限公司介绍,安徽中源管业有限公司电话,安徽中源管业有限公司地址,安徽中源管业有限公司厂家,安徽中源管业有限公司电力管,安徽中源管业有限公司管材
安徽中源管业有限公司
小程序开发|微信小程序,小程序开发,小程序,小程序制作,微信小程序开发,小程序公司,小程序开发公司,分销,三级分销系统,分销系统
小程序开发
云南网站建设|云南网站制作,网站建设,云南网站开发,云南网站设计,云南网页设计,云南网站建设公司,云南网站建设
云南网站建设
外贸网站建设|外贸网站建设,英文网站制作,英文网站设计,美国主机空间,外贸建站平台,多语言网站制作
外贸网站建设
易捷尔高职单招|易捷尔高职单招,易捷尔高职单招培训,单招分数线,单招录取分数线,高职单招学校分数线
易捷尔高职单招

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部