2.Java面向对象编程三大特性之继承
在《Think in Java》中有这样一句话:复用代码是java众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够复用代码并对其加以改变是不够的,他还必须能够做更多的事情。复用代码是我们一直所追求的,而继承则是复用代码的一种方式。
继承的定义:继承是用已有的类(称之为父类或超类)作为基础类建立新类(子类),子类继承父类拥有父类的全部定义,并且子类可以定义新的功能或增加新的数据。使用继承我们可以很方便的复用已有的代码。继承所描述的是“is-a”的关系,有两个对象猫、动物,这两个对象可以描述为“猫是动物”,那么猫就可以继承动物。如果不存在“is-a”的关系则不能继承。
继承定义了类如何相互关联,共享特性,对于若干个相同或者相似的类,我们可以抽象出他们共有的属性和行为并将其定义成一个父类或超类,其他的子类则可以继承这个父类,如有需要子类可以再定义自己独有的属性或行为。
使用继承时需要注意的三点:
(1).子类拥有父类的非private的属性和方法;
(2).子类可以拥有自己的属性和方法,即子类可以对父类进行扩展;
(3).子类可以用自己的方式实现父类的方法。
使用继承有很多的优点,除了可以将几个子类共有的属性放入父类,实现代码共享,避免重复外,还可以使得在修改、扩展继承而来的实现时更加简单。
说到继承就一定要说另外三个东西:构造器(也叫构造函数或构造方法)、protected关键字、向上转型
(1).构造器:
在前面我们知道子类可以继承父类中除了用private修饰的属性和方法,但是除了用private修饰的不能被继承外父类的构造器也是不能被继承的,构造器只能被调用,使用super()方法即可调用。
public class Person {
protected String name;
protected int age;
protected String sex;
Person(){
System.out.println("Person Constrctor...");
}
}
public class Husband extends Person{
private Wife wife;
Husband(){
System.out.println("Husband Constructor...");
}
public static void main(String[] args) {
Husband husband = new Husband();
}
}
Output:
Person Constrctor...
Husband Constructor...
对子类而言,其构造器的正确初始化是非常重要的,而且只有一个方法可以保证这点:在子类的构造器中调用父类的构造器来完成初始化,因为父类构造器具有完成父类初始化所需要的所有知识和能力,所以他能正确的完成子类构造器的初始化。而且编译器会在子类构造器中默认调用父类构造器,不需要我们显示的调用。但是,默认调用父类的构造器是以父类有默认构造器为前提的,如果父类没有默认构造器我们就必须显示的使用super()方法来调用父类构造器,且必须写在子类构造器中的第一行,否则编译器会报错:无法找到符合父类形式的构造器。如下:
public class Person {
protected String name;
protected int age;
protected String sex;
Person(String name){
System.out.println("Person Constrctor-----" + name);
}
}
public class Husband extends Person{
private Wife wife;
Husband(){
super("chenssy");
System.out.println("Husband Constructor...");
}
public static void main(String[] args) {
Husband husband = new Husband();
}
}
Output:
Person Constrctor-----chenssy
Husband Constructor...
(2).protected关键字:
private(受保护的)访问修饰符,对于封装而言,是最好的选择。但有时候需要将某些事物尽可能地对这个世界隐藏,但是仍然允许子类的成员来访问它们,这个时候就需要使用到protected。
对protected而言,它指明所有继承此类的子类或者其他任何位于同一个包的类是可以访问的,但对其他类来说它是private的。 诚然尽管可以使用protected访问修饰符来限制父类属性和方法的访问权限,但是最好的方式还是将属性保持为private(我们应当一致保留更改底层实现),而通过protected方法来控制类的继承者的访问权限。
(3).向上转型:
在上面的继承中我们谈到继承是is-a的相互关系,猫继承与动物,所以我们可以说猫是动物,或者说猫是动物的一种。这样将猫看做动物就是向上转型。如下:
public class Person {
public void display(){
System.out.println("Play Person...");
}
static void display(Person person){
person.display();
}
}
public class Husband extends Person{
public static void main(String[] args) {
Husband husband = new Husband();
Person.display(husband); //向上转型
}
}
在这我们通过Person.display(husband)。这句话可以看出husband是person类型。
将子类转换成父类,在继承关系上面是向上移动的,所以一般称之为向上转型。由于向上转型是从一个叫专用类型向较通用类型转换,所以它总是安全的,唯一发生变化的可能就是属性和方法的丢失。这就是为什么编译器在“未曾明确表示转型”活“未曾指定特殊标记”的情况下,仍然允许向上转型的原因。
(4).慎用继承:
继承存在如下缺陷:
A.父类变,子类就必须变;
B.继承破坏了封装,继承使父类的实现细节对于子类来说都是透明的;
C.继承是一种强耦合关系。
所以说当我们使用继承的时候,我们需要确信使用继承确实是有效可行的办法。那么到底要不要使用继承呢?《Think in java》中提供了解决办法:问一问自己是否需要从子类向父类进行向上转型。如果必须向上转型,则继承是必要的,但是如果不需要,则应当好好考虑自己是否需要继承。
以上内容均来自http://www.cnblogs.com/chenssy/博客,此博客为本人学习笔记
2.Java面向对象编程三大特性之继承的更多相关文章
- Java学习笔记二十一:Java面向对象的三大特性之继承
Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...
- Python - 面向对象编程 - 三大特性之继承
继承 继承也是面向对象编程三大特性之一 继承是类与类的一种关系 定义一个新的 class 时,可以从某个现有的 class 继承 新的 class 类就叫子类(Subclass) 被继承的类一般称为父 ...
- 3.java面向对象编程三大特性之多态
面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对类的外部而言它的内部实现细节是隐藏的,暴露给外界的只是它的实现方法. ...
- Java 面向对象的三大特性之一 继承
继承: Java是继承的三大特性之一,是Java中实现代码重用的手段之一 将重复的代码抽取到父类中继承的有点或者现实 优点: 方便修改代码 减少代码量 Java中继承的语法: 修饰符 SubClass ...
- Java面向对象编程三大特性 --- 多态
多态特性: 子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象 ...
- 1.java面向对象编程三大特性之封装
封装即把一个对象的属性.行为等放在一个实体类中隐藏起来,不允许外部对其进行修改,但是被封装的属性.行为会对外提供一个接口与外部联系,这个对外的接口通常情况下就是set().get()方法.可以通过se ...
- 谈谈Java面向对象的三大特性
Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...
- Java学习笔记二十五:Java面向对象的三大特性之多态
Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...
- Java学习笔记十八:Java面向对象的三大特性之封装
Java面向对象的三大特性之封装 一:面向对象的三大特性: 封装 继承 多态 二:封装的概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访 ...
随机推荐
- gcd(欧几里得算法)
基础 int gcd(int a,int b) { int r; ) { r=a%b; a=b; ...
- iOS8 UIAlertView键盘闪一下的问题
if (SYSTEM_VERSION >= 8.0) { UIAlertController *alertCtrl = [UIAlertController alertControllerWit ...
- dell E6400笔记本 centos7 安装无线网卡
1.下载 驱动:http://download.csdn.net/detail/nj4506/9752842 2.解压: make make install 3.将wk.ko拷贝到 /lib/mo ...
- 07. pt-fifo-split
iostat -dxm 1 42 1>iostat.log 2>&1 ---------------------------------------- #!/bin/bash of ...
- WCF路由服务
代码下载: 链接:https://pan.baidu.com/s/1i76Ht0lMWmosaCrDjaA2cA 密码:muj11.新建类库 Service.Interface using Syste ...
- jvm 基础
1. JDK 包含 java 程序设计语言,JVM, Java API类库. java 开发最小环境 2. JRE : Java API类库中java se API 子集和java 虚拟机(HotSp ...
- JS下拉页面时一个横幅的样式和js
整理之前的代码,发现有一个js,就是页面往下浏览时,上面的商品名称和购买按钮在页面上方悬浮的,就整理下来,代码如下: <script type="text/javascript&quo ...
- [html]Sublime Text添加插件
今天想在Sublime Text(简称ST)内编写HTML后直接使用浏览器看效果,想添加View in Browser插件,然后遇到奇怪的问题添加插件直接报"找不到有用的插件" 一 ...
- python早期看书笔记
- unity中的构造函数
避免使用构造函数 不要在构造函数中初始化任何变量,使用Awake或Start实现这个目的.即使是在编辑模式中Unity也自动调用构造函数,这通常发生在一个脚本被编译之后,因为需要调用构造函数来取向一个 ...