前言
Java是一个面向对象的语言。每一个学习过Java的人都知道,封装、继承、多态是面向对象的三个特征。每个人在刚刚学习继承的时候都会或多或少的有这样一个印象:继承可以帮助我实现类的复用。所以,很多开发人员在需要复用一些代码的时候会很自然的使用类的继承的方式,因为书上就是这么写的(老师就是这么教的)。但是,其实这样做是不对的。长期大量的使用继承会给代码带来很高的维护成本。
其实我第一次学习java 的时候根本没有听说过组合这个名词,老师也更没有讲解过,我一直以为是我自己落掉了什么知识点,其实不是的,组合这个名词暂且把它定义为一个思维性的东西吧,相信读者都接触过了,但是并不知道它还有这个名字。
其实所谓的组合就是创建一个新类去调用已经创建并且调试好的类,那么这个新类就可以把它叫做是一个组合
例如我创建一个People
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class People { private String name; private int age; public void setName(String name){ this .name = name; } public String getName(){ return this .name; } public int getAge(){ return this .age; } public void setAge( int age){ this .age = age; } } |
那我现在要用这个类,我可以给这个类添加一些新的特性,这时候我们就可以创建一个新的类,然后在这个类里创建People的对象。
比如我现在创建一个类叫做Student
1
2
3
|
class Student { People people = new People(); } |
然后可以在这个类里添加一些属性,比如定义个身份为student,在这里我就不在论述了。
接下来看看继承,其实继承和组合本就有异曲同工之妙,先来看看是怎样继承的。
在java里有一个叫做extends的关键字,它可以帮助我们继承,被继承的类我们称作父类,也可以叫做基类,超类都行,而继承者我们称作子类或者派生类等等
这里我们定义一个类
1
2
3
|
public class Student extends People{ //doSomething } |
这样一来的话,该类就继承了父类的全部成员方法和成员变量,但是注意,声明为private权限的字段或者方法是不会被继承下来的。
为了证明这一点我们在student类写一个方法
1
2
3
|
public String re(){ return this .name; } |
这里编译器会报一个错"People.name is not visible",从这里就可以看出,被声明为private 的字段或者方法是不能被继承下来的,如果你想把它继承下来,可以把private改成protected,这样的话,我们就能顺利的继承下name字段。
这样我们把People里的字段全部初始化一下,只需在代码里加上这一段代码块就行了
1
2
3
4
|
{ this .age = 10 ; this .name = "zhangsan" ; } |
接下来在主函数里声明出这个student
1
2
|
Student student = new Student(); System.out.println(student.getAge()); |
现在我们惊讶的发现这个写法是可行的,尽管我们没有在子类中声明任何的字段和方法,我们依然可以调用getAge();并且可以顺利的打印出10
这是因为我们没有在子类中重载任何方法,所以此时调用的是父类的getAge,也就可以轻松的访问到父类的private声明的字段了。
看完了这些相信大家对继承已经有了一个初步的认识,那么在继承机制中,各个类的构造方法又是怎么被调用的呢,答案是自父类到子类依次调用.
演示的同时我先声明三个类Temp1、Temp2、Temp3,与此同时Temp3继承自Temp2,而Temp2又继承自Temp1,这样的话,我们在各个类的构造方法里都放上一句打印的语句
1
2
3
4
5
6
|
//Temp1 System.out.println( "i'm temp1" ); //Temp2 System.out.println( "i'm temp2" ); //Temp3 System.out.println( "i'm temp3" ); |
为了方便我这里就这样写了,但是大家千万要注意这些是放在各个类的构造方法里的。
我们在主函数里创建一个Temp3的对象
1
2
3
4
5
|
public class Mian{ public static void main(String[] args){ Temp3 temp3 = new Temp3(); } } |
我们看控制台,打印出了
1
2
3
|
i'm temp1 i'm temp2 i'm temp3 |
由此可以看出先要创建temp3的对象,发现了extends关键字,然后顺着继承链往上走,找到temp2,又发现extends关键字,接着找到temp1,然后调用temp1的构造方法,接着往下挨个调用。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
原文链接:http://www.cnblogs.com/haodawang/p/5967265.html