背景:对基类和派生类有更清晰的认识。

从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 。但继承并不仅仅是类的复用。当创建了一个派生类的对象时,该类包含了一个基类的子对象。这个子对象和你用基类直接创建的对象没有什么两样。

二者的区别在于,后者来自于外部,而基类的子对象来自于派生类对象的内部。对基类的子对象初始化时至关重要的,而且也只有一种方法来保证这一点,那就是在派生类的构造器中调用基类的构造器,而基类的构造器具有执行基类初始化所需的所有能力和知识。

示例

在无参构造器时, java会自动在派生类的构造器中插入对基类的构造器的调用。

public class Humans {
Humans(){
System.out.println("我是人!");
} }
public class Student extends Humans{  

    Student(){
System.out.println("我是学生!");
} }
public class test {
public static void main(String args[]){
new Student();
}
}

输出结果为:

      我是人!

     我是学生!

可以发现,总是基类的构造器先被初始化。

示例

但是当构造器有参数时,那就必须使用关键字super现实地编写调用基类构造器的代码,并且匹配适当的参数列表。

public class Humans {  

    private String name;  

    Humans(String name){
System.out.println("我是叫"+name+"的人");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{  

    private String name;  

    Student(String name){
super(name);
System.out.println("我是学生!");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
public class test {
public static void main(String args[]){
new Student("zhangsan");
}
}

输出结果:

我是叫zhangsan的人

我是学生!

如果注释掉上面的super(name);将会报错。原因是派生类必须调用基类构造器。因为实例化派生类时,基类也会被实例化,如果不调用基类的构造器,基类将不会被实例化,所以派生类没有调用基类构造器会报错。

但是如果Humans的代码变成这样就不会错。如下代码:

public class Humans {  

    private String name;  

    Humans(){
System.out.println("我是人!");
}
Humans(String name){
System.out.println("我是叫"+name+"的人");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{  

    private String name;  

    Student(String name){
//super(name);
System.out.println("我是学生!");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
public class test {
public static void main(String args[]){
new Student("zhangsan");
}
}

输出结果为:

        我是人!

        我是学生!

原因是,如果基类有一个无参的构造器,就算派生类不用super显示调用基类的构造函数,编译器也会自动去调用基类的无参构造函数。

所以上面的代码不会报错,输出结果也不是

        我是叫zhangsan的人

        我是学生!

而是

        我是人!

        我是学生!

示例

派生类继承了基类的所有public和protected属性和方法,代码如下:

public class Humans {  

    public String sex;  

    protected int age ;  

    private String name;  

    Humans(String sex,String name,int age){
this.sex = sex;
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
public class Student extends Humans{  

    Student(String sex ,String name,int age){
super(sex,name,age);
}
}
public class test {
public static void main(String args[]){
Student s = new Student("男","zhangsan",10);
System.out.println(s.sex);
System.out.println(s.name);
System.out.println(s.age);
}
}

上面的System.out.println(s.name);会报错,因为name是private属性,如需访问,采用get方法:

System.out.println(s.getName())

输出结果为:

男

zhangsan

10 

示例

如果派生类定义了和基类一样的属性或方法,将覆盖基类的属性和方法。如将student改为如下代码:

public class Student extends Humans{  

    public String sex;  

    protected int age ;  

    private String name;  

    Student(String sex ,String name,int age){
super(sex,name,age);
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

输出结果为:

null

null

0

因为只有基类的属性在构造时赋值了,派生类的没有,当访问这些属性时,访问的是派生类的属性,所以全为null或者0。

只有当派生类的属性也被实例化时,才会得到属性的值。代码改为如下:

public class Student extends Humans{  

    public String sex;  

    protected int age ;  

    private String name;  

    Student(String sex ,String name,int age){
super(sex,name,age);
this.sex = sex;
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

输出结果为:


zhangsan
10  

要注意的是,super必须在构造器的最前面,不然会报错

Java基类和派生类的更多相关文章

  1. 详解C++中基类与派生类的转换以及虚基类

    很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...

  2. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

  3. (转) C++中基类和派生类之间的同名函数的重载问题

    下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...

  4. c++中基类与派生类中隐含的this指针的分析

    先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...

  5. C++学习21 基类和派生类的赋值

    在C/C++中,经常会发生数据类型转换,例如整型数据可以赋值给浮点型变量,在赋值之前,先把整型数据转换为浮点型:反过来,浮点型数据也可以赋值给整型变量. 数据类型转换的前提是,编译器知道如何对数据进行 ...

  6. 基类和派生类--this

    基类指针在程序运行的时候的确指向的是一个派生类的对象,但指针的类型仍然是基类指针.C++是一种强类型语言,因此不能用基类指针类型的指针直接调用派生类:而且,同一个类可能有多种不同的派生类,因此不知道实 ...

  7. C++:基类与派生类对象之间的赋值兼容关系

    4.5 基类与派生类对象之间的赋值兼容关系 在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量. 在赋值之前,先把整型数据转换为双精度型数据,然后再把它双精度型变量. ...

  8. C++:基类和派生类

    4.1 派生类的声明 继承实例如下: class Person{ //声明基类Person public: void print() { cout<<"name:"&l ...

  9. C++基类和派生类之间的转换

    本文讲解内容的前提是派生类继承基类的方式是公有继承,关键字public 以下程序为讲解用例. #include<iostream> using namespace std; class A ...

随机推荐

  1. TRIO-basic指令--FLEXLINK

    Type: Axis Command Syntax: FLEXLINK(base_dist, excite_dist, link_dist, base_in, base_out, excite_acc ...

  2. Dethe is my Finaunce金融

    英国诗人乔叟Dethe is my Finaunce金融 英语中“金融”在14世纪,金融计算时间价值的手段.就随机结果签约的能力.一个允许转让金融权后的清算.<Lamentation of Ma ...

  3. 分布式监控系统Zabbix3.4-针对MongoDB性能监控操作笔记

    公司在IDC机房的一台服务器上部署了MongoDB,由于所存储的业务数据比较重要,所以对MongoDB的监控显得尤为重要!Zabbix监控MongoDB性能的原理:通过echo "db.se ...

  4. B. Vasya and Isolated Vertices

    链接 [http://codeforces.com/contest/1065/problem/B] 题意 给你n个点,m条边,让你找最多孤立点和最少孤立点,不能有自环路 分析 对于最少max(0,n- ...

  5. <编写有效用例>读书笔记3

    <编写有效用例>读书笔记3 第三部分主要内容是对忙于编写用例的人的提示第20章:对每个用例的提示1.每个用例都是一篇散文:这个提示提醒我们将注意力集中与文字而不是图画上,同时帮助了解将要遇 ...

  6. 常见IP端口

    21端口:21端口主要用于FTP(File Transfer Protocol,文件传输协议)服务. 23端口:23端口主要用于Telnet(远程登录)服务,是Internet上普遍采用的登录和仿真程 ...

  7. PAT 甲级 1134 Vertex Cover

    https://pintia.cn/problem-sets/994805342720868352/problems/994805346428633088 A vertex cover of a gr ...

  8. mysql学习笔记二 —— 权限体系

    要点: 1.MySQL的API2.MySQL的相关文件3.MySQL的权限体系 1.MySQL的API 应用程序接口 (application program interface) 1.1 命令行中的 ...

  9. pxe+kickstart 自动化部署linux操作系统

    kickstart 是什么? 批量部署Linux服务器操作系统 运行模式: C/S client/server 服务器上要部署: DHCP tftp(非交互式文件共享) 安装系统的三个步骤: 1.加载 ...

  10. 一步步分析为什么B+树适合作为索引的结构

    在MySQL中,主要有四种类型的索引,分别为:B-Tree索引,Hash索引,Fulltext索引和R-Tree索引,本文讲的是B-Tree索引. 什么是索引 索引(Index)是帮助数据库高效获取数 ...