What?
什么是继承?通俗点来讲,父亲生了一个儿子,儿子从父亲身上遗传了一些特点,就是继承。正式的说,继承就是一个类可以从其他类那里继承一些features(包括fields还有methods)。
这里有一些术语要了解一下
Super Class:被继承了features的类就叫做super class还有其他的名字叫做(base class或者父类,也就是parent class)
Sub Class:相应的,从别的类那里继承了features的类就叫做子类,或者叫做derived class, extended class, child class,总之都是子类的意思。除了父类的fields和方法之外,子类还可以有自己的fields和method(比如说你从父亲那里继承了好嗓子,后来又学习了吉他,但是你的父亲是不会吉他的)
Reusability: 继承也支持了reusability的理念,比如说我们想建一个新的class,这个时候我们发现有一个已经写好的class,他里面已经有了一些我们需要用到的方法,我们就可以直接继承这个已经存在的类。(by reusing its fields and methods)
Why?
目前我的理解,继承最大的好处就是reusability。可以通过使用已经写好的东西来写新的东西,可以节省大量的代码和开发时间。(之后如果有新的理解再加入进来)
补充:实际中,继承和多态经常一起被使用,用来实现更快的perfomance和更好的代码可读性。
How?
Java中的keyword, extends (调用父类使用super()). 具体实现看自己写的代码~
简单的解释,当一个子类的对象被创建的时候(他继承了一个父类)。这个父类的所有method以及fields都会在这个对象中请求内存(注意!!是在这个子类的object中请求资源!!也就是说在继承中,当创建一个子类的对象时,父类没有被创建任何对象,他只是在这个时候请求了一定资源,来加载他的内容而已)。这就是为什么我们可以使用子类的对象来访问父类的成员的原因了。(一定要了解,当一个子类对象被创建时,父类不创建对象!!只有一个包含着父类变量的子类对象会被创建!!)
// A Java program to demonstrate that both super class
// and subclass constructors refer to same object
// super class
class
Fruit
{
public
Fruit()
{
System.out.println(
"Super class constructor"
);
System.out.println(
"Super class object hashcode :"
+
this
.hashCode());
System.out.println(
this
.getClass().getName());
}
}
// sub class
class
Apple
extends
Fruit
{
public
Apple()
{
System.out.println(
"Subclass constructor invoked"
);
System.out.println(
"Sub class object hashcode :"
+
this
.hashCode());
System.out.println(
this
.hashCode() +
" "
+
super
.hashCode());
System.out.println(
this
.getClass().getName() +
" "
+
super
.getClass().getName());
}
}
// driver class
public
class
Test
{
public
static
void
main(String[] args)
{
Apple myApple =
new
Apple();
}
}
|
output:
super class constructor super class object hashcode :366712642 Apple sub class constructor sub class object hashcode :366712642 366712642 366712642 Apple Apple
(选自https://www.geeksforgeeks.org/gfact-52-java-object-creation-of-inherited-classes/)
子类可以继承父类的所有特性,但是他的可见性,是由父类成员变量、方法的修饰符决定。对于被private修饰的父类的成员变量或者方法,子类是不可以访问的。对于定义为默认访问(没有修饰符修饰)的父类的methods和fields,只有跟父类在一个package下的子类可以访问。对于定义为public或protected的类成员变量或者方法,所有的子类都可以访问!
当在子类中声明与父类同名的变量的时候,父类的变量就被隐藏起来了,这个时候子类中直接访问的是子类的变量。
子类中可以声明与父类同名的方法,如果返回值类型、方法名、参数都一样,这就是方法的覆盖。
如果想在子类中访问父类中定义的变量或者方法,使用super关键字。有三种情况 super.variable, super.method(), 已经super();这里要注意的是super().他是在调用父类的构造函数,他只能在子类的构造函数中出现,并且永远都是位于子类构造函数中的第一条语句!(为什么?首先不是第一条,会出现编译不通过的情况,因为JAVA中每个子类构造方法的第一条语句,都是隐含地调用了super(),如果父类没有这种形式的构造函数,编译的时候就会直接报错)
Java中继承的different types(图源同上述代码)
1. Single Inheritance:
2.Mutilevel Inheritance:
注意!在Java中,一个类是不能直接访问grandparent的成员的,会编译报错!!只能通过先访问父类,然后通过父类中使用super再去一层层向上访问
3.Hierarchical Inheritance:
简单来说,就是一个父类可以被多个子类继承
4. Mutiple Inheritance:
注意了,Java是不支持类间的多重继承的!!但是不证明Java不能做到多重继承。下图中就是一个例子,A和B是接口,C是一个类。也就是说Java中的多重继承可以通过接口来实现!(不能简单的通过extends class来实现)
5. Hybrid Inheritance(Through Interfaces):
混合使用。因为Java不支持关于类的多重继承,我们可以使用interface来实现java中的混合继承。
总结关于继承要记住的一些概念:
1.Object类是没有父类的,除了他之外,在java中每一个类有且仅有一个直接的父类,每一个类都是Object的子类。
2.一个父类可以有多个子类,一个子类只能有一个父类。
3.一个子类可以继承父类所有的成员(包括方法,变量,甚至!nested classes!!)。但是因为Constructors构造器不是members,所以他们不能被子类继承。但是父类的constructors可以被子类通过super()来进行调用。
4.子类是不能继承父类的私有成员的。但是,如果父类有public或者protected的方法(比如说setters, getters)可以访问父类的private fields,子类就可以利用这些方法来访问父类的私有成员了。