在《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面向对象编程三大特性之继承的更多相关文章

  1. Java学习笔记二十一:Java面向对象的三大特性之继承

    Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...

  2. Python - 面向对象编程 - 三大特性之继承

    继承 继承也是面向对象编程三大特性之一 继承是类与类的一种关系 定义一个新的 class 时,可以从某个现有的 class 继承 新的 class 类就叫子类(Subclass) 被继承的类一般称为父 ...

  3. 3.java面向对象编程三大特性之多态

    面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对类的外部而言它的内部实现细节是隐藏的,暴露给外界的只是它的实现方法. ...

  4. Java 面向对象的三大特性之一 继承

    继承: Java是继承的三大特性之一,是Java中实现代码重用的手段之一 将重复的代码抽取到父类中继承的有点或者现实 优点: 方便修改代码 减少代码量 Java中继承的语法: 修饰符 SubClass ...

  5. Java面向对象编程三大特性 --- 多态

    多态特性: 子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象 ...

  6. 1.java面向对象编程三大特性之封装

    封装即把一个对象的属性.行为等放在一个实体类中隐藏起来,不允许外部对其进行修改,但是被封装的属性.行为会对外提供一个接口与外部联系,这个对外的接口通常情况下就是set().get()方法.可以通过se ...

  7. 谈谈Java面向对象的三大特性

    Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...

  8. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

  9. Java学习笔记十八:Java面向对象的三大特性之封装

    Java面向对象的三大特性之封装 一:面向对象的三大特性: 封装 继承 多态   二:封装的概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访 ...

随机推荐

  1. 1C - A + B Problem II

    I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum o ...

  2. Oracle的SQL语句中如何处理‘&’符号

    ‘&’符号在SQL中有特殊含义,所以在SQL中想要写入&,需要特殊处理. 如下SQL语句就不能正确运行: SQL> select 'a&b' from dual; 处理方 ...

  3. Java 7.35 游戏:猜字游戏(C++&Java)

    Ps: 有人可能好奇我为什么大费周章的去写主函数,而不直接把所有操作放在类中,Why?类就好比骨干(存放核心的数据和功能),最好提供接口, 避免了类中的输入输出,当然,这也不是绝对的. C++: #i ...

  4. PAT 1042 字符统计(20)(思路)

    1042 字符统计(20)(20 分) 请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过1000的字符串.字符串由ASCII码表中任意可见字符及空格 ...

  5. iOS.mach_absolute_time

    1. Technical Q&A QA1398 Mach Absolute Time Units https://developer.apple.com/library/mac/qa/qa13 ...

  6. Android.API.Context.getFilesDir()

    1. Context.getFilesDir() http://developer.android.com/reference/android/content/Context.html#getFile ...

  7. VS2010插件 VS.PHP 调试开发php程序

    VS 插件VS.PHP 调试PHP的方法;不得不说vs强大啊,此断点调试功能在zend都做不到 如图: 设置成功之后,就可以像调试 .Net程序一样试调Php程序了! 调试的步骤: 1.在需要调试的地 ...

  8. python文件读取操作、序列化

    1.对文件进行读写操作时,先建立文件句柄 f = open("test.txt","r",encoding="UTF-8") 其中,r为文件 ...

  9. Tomcat+Redis+Nginx实现session共享(Windows版)

    redis安装:xx nginx安装:xx 步骤: 1.下载tomcat-redis-session-manager相应的jar包,主要有三个: wget https://github.com/dow ...

  10. js 光标位置处理

    /** * 获取选中文字 * 返回selection,toString可拿到结果,selection含有起始光标位置信息等 **/ function getSelectText() { var tex ...