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

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

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

示例

在无参构造器时, 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. Ceph分布式存储-原理介绍及简单部署

    1)Ceph简单概述Ceph是一个分布式存储系统,诞生于2004年,最早致力于开发下一代高性能分布式文件系统的项目.Ceph源码下载:http://ceph.com/download/.随着云计算的发 ...

  2. Gitlab环境快速部署(RPM包方式安装)

    之前梳理了一篇Gitlab的安装CI持续集成系统环境---部署Gitlab环境完整记录,但是这是bitnami一键安装的,版本比较老.下面介绍使用rpm包安装Gitlab,下载地址:https://m ...

  3. NSCache的简单使用

    简介 1)NSCache 是苹果官方提供的缓存类,用法与 NSMutableDictionary 的用法很相似,在 AFNetworking 和 SDWebImage 中,使用它来管理缓存. 2)NS ...

  4. c#代码分析

    代码分析是在一个IT行业计算机程序员必须要具有的基本专业技能,在了解一定的专业基础之上去看懂别人编写的代码,分析别人代码实现的功能,以及基本的维护和扩展测试.不同的人有不同的代码风格,要使自己的能要别 ...

  5. individual reading task ---12061183 叶露婷

    Different people deserve different tasks; Once team roles are settled, there comes along a lot of ot ...

  6. 01springboot快速入门

    SpringBoot快速入门 springboot的宗旨是习惯大于配置,所以spring里面大量使用了默认的配置来简化spring的配置.spring Boot的主要优点: 为所有Spring开发者更 ...

  7. Sprint 冲刺第三阶段第3-5天 数据库代码

    数据库代码: package com.example.brdemo; import android.app.Activity; import android.content.Intent; impor ...

  8. Activiti的BPMN演示工具

    场景是这样的:产品经理不懂技术,又不想安装Java以及Eclipse(需要安装Activiti BPMN Designer的插件). 这两天解决.bpmn的解析(BPMNParser)时顺带找到一个顺 ...

  9. Using Android Phone to recover SD card formatted with DD command under linux

    Using Android Phone to recover SD card formatted with DD command under linux 1. Formatted a sd card ...

  10. CentOS 7 Install Adobe Flash Player

    From Officail Adobe Flash Site don't down (YUM )adobe-release-x86_64-1.0-1.noarch.rpm,but to downloa ...