class Person {
private String name; //私有域
public Person() {
System.out.println("Person() 无参构造器");
name = "noName";
public Person(String name) {
System.out.println("Person(String name) 带参构造器");
this.name = name;
public String getName() { return name;} //让子类可以间接访问到私有域name
public String toString() { return "Person: "+name; }
class Student extends Person{
public Student() {
//默认调用 super(); 表示调用父类的无参构造器
System.out.println("Student() 无参构造器");
public Student(String name) {
super(name); //调用父类的带参构造器
System.out.println("Student(String name) 带参构造器");
public String toString() { return "Student: " + getName();}
public class ExtendsExample {
public static void main(String[] args) {
System.out.println(new Student());
System.out.println(new Student("sakura"));
output:
Person() 无参构造器
Student() 无参构造器
Student: noName
Person(String name) 带参构造器
Student(String name) 带参构造器
Student: sakura
子类和父类的构造器调用问题
关于构造器的调用顺序在前面提过,这里再着重介绍下子类和父类的构造器调用问题。
先有父才有子,Java中使用super关键字表示超类也就是父类。若是子类中没有显式调用父类的构造器,那么编译器就会默认调用super(),即父类的默认构造器;若是父类没有默认构造器,则子类中就必须显式调用父类的带参构造器,并且调用必须放在构造器中的第一行。
super()和this()可以同时存在吗?
super()和this()是不能同时出现在构造器中,因为二者都要求被放在构造器的首行。
组合和继承之间的区别
组合和继承都允许在新的类中放置子对象,组合是显式这样做,而继承则是隐式这样做。
组合技术通常是用于想在新类中使用现有类的功能而非其接口的情况。即,在新类中嵌入某个对象,让其实现所需要的功能;新类的用户看到的只是为新类所定义的接口,而非所嵌入类的接口。
继承是使用某个现有类并开发其特殊版本,会拥有现有类的接口并且可以为新类开发新的接口。
所以,继承关系为“is-a”(是一个),组合关系为“has-a”(有一个)。
protected关键字
在实际的项目中,经常会想要将某些事物尽可能对这个世界隐藏起来,但是仍然允许导出类的成员访问它们。protected
关键字就是实现这个作用。
它表明:对于任何继承于此类的导出类或者任何与此类在同一个包中的类来说,被protected修饰的方法和域是可以访问的,但是对于除这两种类的其他类则是不可访问的。
继承的局限
Java中继承的局限便是不允许类似C++那样的多继承,至于为什么没有多继承最直接的原因就为简单编程,不用去考虑父类的父类是谁、父类的父类的父类是谁、以及自己包含的方法继承自谁的。比如B和C继承自A,D又继承B、C,当D调用A中的一个方法时,是继承自B的还是继承自C的呢?
为了实现多继承的效果的话可以使用多层继承(A继承B,B继承C),但是最好不要超过三层,否则代码会太乱。后面会介绍Java使用接口实现多继承。一个类虽然不能从继承多个基类但是可以声明继承多个接口(interface),从而达到多继承效果。
继承和组合都可以从现有类型生成新类型。组合一般是将现有类型作为新类型的底层实现的一部分来加以复用,而继承复用的是接口。在使用继承时,由于导出的类具有基类的接口,因此它可以向上转型至基类,这对后面要介绍的多态是至关重要的。
[1] Eckel B. Java编程思想(第四版)[M]. 北京: 机械工业出版社, 2007
每天进步一点点,不要停止前进的脚步~