Java基础08 继承(转载)
类的继承
class Human{
public int getHeight(){
return this.height;
}
public void growHeight(int h){
this.height = this.height + h;
}
public void breath(){
System.out.println("hu..hu..");
}
private int height;
}
从上面的类定义,我们可以了解该类的所有细节: 该类的数据成员,该类的方法,该类的接口。
现在要定义一个新的类,比如Woman类,并假设Woman与Human类相当类似:
可以像以前一样,从头开始,完整的定义Woman类:
Woman类只新增了一个giveBirth()方法 (该方法创建并返回一个新的Human对象)。
class Woman{
public int getHeight(){
return this.height;
}
public void growHeight(int h){
this.height = this.height + h;
}
public void breath(){
System.out.println("hu..hu..");
}
public Human giveBirth(){
System.out.println("Give Birth");
return (new Human(20));
}
private int height;
}
利用继承,可以避免上面的重复。让Woman类继承自Human类,Woman类就自动拥有了Human类中所有public成员的功能。
用extends关键字表示继承:
public Human giveBirth(){
System.out.println("Give Birth");
return (new Human(20));
}
}
通过继承,我创建了一个新类,叫做衍生类(derived class)。被继承的类(Human)称为基类(base class)。衍生类以基类作为自己定义的基础,并补充基类中没有定义的giveBirth()方法。
可以用以下Test类测试:
public class Test{
public static void main(String[] args){
Woman aWoman = new Woman();
aWoman.growHeight(120);
System.out.println(aWoman.getHeight());
}
}
衍生层
通过继承,我们创建了Woman类。整个过程可以分为三个层次: 基类定义,衍生类定义,外部使用。
基类定义的层次就是正常的定义一个类,比如上面的Human类定义。
在外部使用者看来(比如Test类中创建Woman类对象),衍生类有一个统一的外部接口:
对于外部使用者来说,上述接口就已经足够了。仅从接口看,衍生类也没有什么特别之处。
然而,当程序员在衍生类定义的层次时,就必须要小心:
首先,接口是混合的: getHeight()方法和growHeight()方法来自基类,giveBirth()方法则是在衍生类内部定义的。
还有更加复杂的地方。我们之前在类的内部可以自由访问类的成员(利用this指代对象)。然而,当我们在Woman类的定义范围内,我们无法访问基类Human的private成员。我们记得private的含义: private的成员仅供该类内部使用。Woman类是一个不同于Human类的新类,所以位于Human类的外部。在衍生类中,不能访问基类的private成员。
但有趣的是,我们的growHeight()和getHeight()方法依然可以运行。这说明基类的private成员存在,我们只是不能直接访问。
为了清晰概念,我们需要了解衍生类对象的生成机制。当我们创建一个衍生类的对象时,Java实际上先创建了一个基类对象(subobject),并在基类对象的外部(注意,这里是基类对象的外部,衍生类对象的内部),增加衍生类定义的其他成员,构成一个衍生类对象。外部使用者能看到的,就是基类和衍生类的public成员。
图中黄色为基类对象。基层的成员之间可以互相访问 (利用Human类定义中的this指代基类对象)。
蓝色部分为衍生对象新增的内容,我将这部分称为衍生层。蓝色和黄色部分共同构成衍生对象。衍生层的成员可以相互访问(Woman定义中的this)。更进一步,我们还可以访问基层中public的成员。为此,我们用super关键字来指代基类对象,使用super.member的方式来表示基层的(public)成员。
当我们位于衍生层时(也就是在定义Woman类时),不能访问红色的基层private成员。当我们位于外部时,既不能访问紫色的衍生层private成员,也不能访问红色的基层private成员。
(衍生层的private成员有访问禁忌,所以标为斜线。基层的private成员访问禁忌最多,所以标为交叉斜线)
super和this类似,也是隐式参数。我们在类定义的不同层次时,this会有不同的含义。要小心的使用this和super关键字。
(Java并不强制使用this和super。Java在许多情况下可以自动识别成员的归属。)
protected
我们之前介绍了两个访问权限相关的关键字,private和public,它们控制了成员的外部可见性。现在,我们介绍一个新的访问权限关键字: protected。
标为protected的成员在该类及其衍生类中可见。这个概念很容易理解,就是说,基类的protected成员可以被衍生层访问,但不能被外部访问
方法覆盖
衍生类对象的外部接口最终由基类对象的public成员和衍生层的public成员共同构成。如果基类public成员和衍生层的public成员同名,Java接口中呈现的究竟是哪一个呢?
我们在构造方法与方法重载中已经提到,Java是同时通过方法名和参数列表来判断所要调用的方法的。方法是由方法名和参数列表共同决定的。上述问题中,如果只是方法名相同,而参数列表不同,那么两个方法会同时呈现到接口,不会给我们造成困扰。外部调用时,Java会根据提供的参数,来决定使用哪个方法 (方法重载)。
如果方法名和参数列表都相同呢? 在衍生层时,我们还可以通过super和this来确定是哪一个方法。而在外部时,我们呈现的只是统一接口,所以无法同时提供两个方法。这种情况下,Java会呈现衍生层的方法,而不是基层的方法。
这种机制叫做方法覆盖(method overriding)。方法覆盖可以被很好的利用,用于修改基类成员的方法。比如,在衍生层,也就是定义Woman时,可以修改基类提供的breath()方法:
public Human giveBirth(){
System.out.println("Give birth");
return (new Human(20));
}
public void breath(){
super.breath();
System.out.println("su..");
}
}
注意,此时我们位于衍生层,依然可以通过super来调用基类对象的breath()方法。当我们外部调用Woman类时,由于方法覆盖,就无法再调用基类对象的该方法了。
方法覆盖保持了基类对象的接口,而采用了衍生层的实现。
构造方法
在了解了基类对象和衍生层的概念之后,衍生类的构造方法也比较容易理解。
我们要在衍生类的定义中定义与类同名的构造方法。在该构造方法中:
- 由于在创建衍生对象的时候,基类对象先被创建和初始化,所以,基类的构造方法应该先被调用。我们可以使用super(argument list)的语句,来调用基类的构造方法。
- 基类对象创建之后,开始构建衍生层 (初始化衍生层成员)。这和一般的构建方法相同,参考构造方法与方法重载
比如下面的程序中,Human类有一个构造方法:
public Human(int h){
this.height = h;
}
public int getHeight(){
return this.height;
}
public void growHeight(int h){
this.height = this.height + h;
}
public void breath(){
System.out.println("hu..hu..");
}
private int height;
}
class Woman extends Human{
public Woman(int h){
super(h);//base class construnctor
System.out.println("Hello,Pandora!");
}
public Human giveBirth(){
System.out.println("Give Birth");
return (new Human(20));
}
public void breath(){
super.breath();
System.out.println("su..");
}
}
Java基础08 继承(转载)的更多相关文章
- Java基础08 继承
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 继承(inheritance)是面向对象的重要概念.继承是除组合(composit ...
- 第二十八节:Java基础-进阶继承,抽象类,接口
前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...
- Java基础学习-- 继承 的简单总结
代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...
- Java基础--定时任务Timer(转载)
Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...
- java基础之继承(一)
虽然说java中的面向对象的概念不多,但是具体的细节还是值得大家学习研究,java中的继承实际上就是子类拥有父类所有的内容(除私有信息外),并对其进行扩展.下面是我的笔记,主要包含以下一些内容点: 构 ...
- 【Java基础】继承的一些总结
什么是继承 把一些类的具有共性的东西剥离出来形成一个新的类,然后各个其他类保留自己独有的特性,并用关键字extends继承这个剥离出来的新的类,可以最终达到各类原始相同效果,但是在每个类中,单用一个“ ...
- JAVA基础知识点(转载的)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/8846697 1.使用浮点型数值时,默认的类型是double,后面加上f或F才被识别为flo ...
- Java基础—注解(转载)
概念 注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面 ...
- Java基础—内部类(转载)
转载自:java中的匿名内部类总结 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部 ...
随机推荐
- linux之touch命令修改文件的时间戳
功能:对已经存在文件的时间进行修改,存取时间(access time).修改时间(modification time).对不存在的文件,进行创建新的空白文件. 语法:touch [选项] 文件 ...
- msgfmt: command not found
sudo apt-get install gettext
- linux上虚拟显示器和火狐浏览器的使用学习记录
Ubuntu 14.04 sudo apt-get firefox sudo apt-get install python-pip sudo apt-get install xvfb# xserver ...
- min-height IE6的解决方案
selector { min-height:500px; height:auto !important; height:500px; } 因为IE6中当内容大于容器高度或宽度时,就会撑破容器.并且在同 ...
- javascript 的事件绑定和取消事件
研究fabricjs中发现,它提供canvas.on('mousemove', hh) 来绑定事件, 提供 canvas.off()来取消绑定事件这样的接口,很是方便, 那我们就不妨探究一下内在的实现 ...
- CentOS 7 yum安装失败问题
在CentOS 7中,执行yum安装,一直报错,错误信息如下 其实在上述的错误信息中,上述中的repodata/repomd.xml文件据说是/mnt目录rpm包的目录,路径 在/mnt中因为没有/r ...
- Apache 配置:是否显示文件列表
Apache 配置:是否显示文件列表 进入虚拟主机配置文件 显示文件列表的话 options Indexes FollowSymLinks 不显示文件列表的话 options FollowSymLin ...
- jQuery OCUpload ——> 一键上传插件
OCUpload为jQuery的插件(One Click Upload),意思为一键上传,封装了对于文件上传的一些方法,只需几行代码,文件上传优雅而简洁. 对于传统的文件上传,只是通过inp ...
- CStdioFile类学习笔记<转>
本文转自:http://www.cnblogs.com/JiMuStudio/archive/2011/07/17/2108496.html CStdioFile类的声明保存再afx.h头文件中. ...
- TCP/IP ---分层
TCP/IP的分层 ICMP是IP协议的附属协议.IP层用它来与其他主机或路由器交换错误报文和其他重要信息.尽管ICMP主要被IP使用,但应用程序也有可能访问它.我们将分析两个流行的诊断工具,Ping ...