相关文章:

  1. 《面向对象再探究》:介绍了面向对象的基本概念
  2. 《详解Java的对象创建》:介绍了对象的创建、构造器的使用

《面向对象再探究》这篇文章中已经笼统的介绍过继承的概念了,下面就来具体介绍继承的使用等相关问题。

1. 引入例子

Animal类和Dog类例子,下文都会围绕该例展开。

public class Animal {
private String name;
private int age; public Animal(String name, int age) {
this.name = name;
this.age = age;
} public Animal() {
} public void say() {
System.out.println("我是" + name + ",今年" + age + "岁了");
} //getters and setters ...
}
public class Dog extends Animal {

    private String address;

    public Dog(String name, int age, String address) {
super(name, age);
this.address = address;
} public Dog() {
} public void say() {
System.out.println("我叫" + super.getName() + ",今年" + super.getAge() + "岁了,家住" + address + ",汪汪汪...");
} public void watchDoor() {
System.out.println("我在" + address +"看门...");
} //getters and setters ...
}

Dog类继承Animal类,Animal类有nameage属性和say()方法,Dog类增加了address属性和watchDoor()方法。

2. 概念介绍

在现实生活中有许多继承的例子,比如“子承父业”、“继承父母财产”、“继承某人意志”等,这些都是在强调一个体得到另一个体的东西,他们之间存在“继承关系”。

在Java中,继承是类和类之间的关系。在《面向对象再探究》这篇文章中举了动物Animal类和狗Dog类、猫Cat类、兔子Rabbit类的例子并写了代码,这里直接拿来用不再列出,请移步此文章。

我们可以说狗、猫、兔子是动物,但不可以说动物是狗、猫、兔子。动物普遍有眼睛、耳朵等属性,有跑、吃、叫等行为。狗显然也具有这些属性和行为,但是狗也具有一些它特有的属性和行为,比如灵敏的鼻子、看门等。

在这个例子中,Animal类是父类,Dog类、Cat类、Rabbit类是子类。子类和父类存在继承关系,可以说:子类“是”父类,该关系是继承的一个明显特征。

下面是关于继承的几个Q&A:

Q1: 什么时候需要用到继承?

A1: 个人认为可从以下两点出发:

  1. 面向对象语言是对现实世界的抽象,所谓“万物皆对象”,那么我们在实际开发中的类肯定都是与现实世界的实物相对应的,所以看实物之间的关系有没有继承关系。
  2. 当有若干类有大量重复的属性和方法,那么就可以考虑使用继承,将这些重复的属性和方法抽成父类。

Q2: 怎样使用继承?

A2: 子类使用extends关键字继承父类,也只有使用了该关键字后,才存在继承关系及“父子类”:

public class Animal {//父类
//属性和方法
}
public class Dog extends Animal {//子类继承父类
//属性和方法
}

Q3: 在具体开发中,是先编写父类,然后扩展出子类,还是先编写子类,然后抽象出父类?

A3: 个人认为不能一概而论。如果你的系统设计非常好,可以先写好父类,然后扩展子类。如果你没设计好,或者考虑不周,那么后期可能会出现许多类有重复代码,这时候可以考虑抽取父类。

Q4: 父类和子类在内容上有什么区别?

A4: 通常,我们将更通用的一些属性和方法放到父类中,比如狗、猫、兔子都具有的属性和方法会方法动物类中。子类中是更加特别的属性和方法,比如狗的看门行为、猫的抓老鼠行为。由于子类继承了父类,所以子类中只需要编写和父类的不同之处。

所以,子类往往会比父类拥有更加丰富的属性和方法。

Q5: 子类继承的父类的哪些东西?

A5: 这里先给出结论,下文再详细介绍。子类继承了父类的非私有private成员变量、方法、嵌套类,子类不继承父类的构造器,但是子类可以调用父类的构造器。

Q6: Java中可以继承多个类吗?

A6: Java中的继承是单继承,只能继承一个类。

3. 具体使用

3.1. 子类重写父类的方法

有时子类从父类继承得到的方法不一定适用,这时子类可以重写父类的方法。如Dog类重写了其父类的say()方法。

注意要和重载加以区分。

简单来说,重写涉及到的是两个类的同名方法,重载涉及到的是一个类的同名方法。关于重载介绍请移步这里

3.2. 子类新增属性和方法

前面提到:子类是对父类的扩展,子类内容比父类更加丰富。所以通常子类都会有自己的属性和方法,比如Dog类的address属性和watchDoor()方法。

3.3. 子类如何使用父类的私有成员?

子类不继承父类的私有成员,但是如果父类有能访问其私有成员变量的publicprotected的方法(比如getter方法),那么子类可以通过继承这些方法来使用父类的私有方法(Java官方教程)。

下面用上面的代码例子解释:

Animal类有私有成员变量、和公有方法say()say()直接访问本类的私有成员变量,没毛病!

public class Animal {
private String name;
private int age; public void say() {
System.out.println("我是" + name + ",今年" + age + "岁了");
}
//其他代码...
}

现在Dog类继承Anima

public class Dog extends Animal {

    private String address;

    public void say() {//name和age报红
System.out.println("我叫" + name + ",今年" + age + "岁了,家住" + address + ",汪汪汪...");
} //其他代码...
}

请注意Dog类的say()方法,直接访问了nameage属性,如果子类继承了父类的私有成员,那么这样写是没问题的,但事实是nameage报红了,说明子类没有继承父类的私有成员。

虽然子类没有继承父类的私有成员,但是我们可以通过父类的公有方法使用其私有成员变量,代码改动如下:

public class Dog extends Animal {

    private String address;

	public void say() {
System.out.println("我叫" + super.getName() + ",今年" + super.getAge() + "岁了,家住" + address + ",汪汪汪...");
} //其他代码...
}

使用super.xxx()可以调用父类的方法,由于getName()是父类公有方法,且能访问父类的私有成员变量name,所以子类调用getName()方法可以使用name变量。

3.4. 子类如何对父类的私有成员赋值?

子类没有继承父类的私有成员变量,当然不能直接赋值。通常有两种方法:调用父类的公有setter方法或调用父类的构造器。本质上还是子类通过使用父类提供的公有方法(setter或构造器)使用其私有成员变量。

3.4.1. 使用setter方法:

public class Dog extends Animal {

    private String address;

    public void setName(String name) {
super.setName(name); //注意super
} public void setAge(int age) {
super.setAge(age);
} public void say() {
System.out.println("我叫" + super.getName() + ",今年" + super.getAge() + "岁了,家住" + address + ",汪汪汪...");
} //其他代码...
}

Dog类的两个setter方法调用了Animal类的两个setter方法,由于子类的setter方法名和父类的setter方法名取得一样(重写了),所以一定要使用super关键字加以区分,否则就成递归了。

3.4.2. 调用父类的构造器:

public class Dog extends Animal {

    private String address;

    public Dog(String name, int age, String address) {
super(name, age); //调用父类构造器
this.address = address;
} public Dog() {
} public void say() {
System.out.println("我叫" + super.getName() + ",今年" + super.getAge() + "岁了,家住" + address + ",汪汪汪...");
} //其他代码...
}
public class Animal {
private String name;
private int age; public Animal(String name, int age) {
this.name = name;
this.age = age;
} //其他代码...
}

子类使用super()语句调用父类构造器,该语句必须是子类构造器的第一行代码。

如果子类构造器没有显式调用父类构造器,则会默认调用父类的无参构造器。所以如果父类没有无参构造器,而子类又没有显式调用父类的其他构造器,则会报错。

4. 关于我

如有错误,还请指正。

一文打尽Java继承的相关问题的更多相关文章

  1. java继承属性相关介绍

    这个只需要记住一点,父类的任何属性(变量可以看做属性),子类均可继承并覆盖,allType(father)-->changeAnyType(son)-->AnyType 这是父类的所有代表 ...

  2. 一文打尽Java抽象类和接口的相关问题

    相关文章: <面向对象再探究>:介绍了面向对象的基本概念 <详解Java的对象创建>:介绍了对象的创建.构造器的使用 <一文打尽Java继承的相关问题>:介绍了继承 ...

  3. Java继承相关知识总结

    Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...

  4. 【Java初探01】——Java简介及相关

    Java 简介 java 是一种高级的面向对象的程序设计语言,使用Java语言编写的程序时跨平台的.从pc到手机,都有Java开发的程序和游戏,Java程序可以在任何计算机,操作系统和支持的Java的 ...

  5. JAVA继承时构造函数的问题

    今天看到java继承部分时,关于构造函数是否继承以及如何使用时遇到了点问题,后来查找相关资料解决了. 下面是我个人的总结: 先创建一个父类,里面有两个构造函数: public class Jisuan ...

  6. 【Socket编程】Java中网络相关API的应用

    Java中网络相关API的应用 一.InetAddress类 InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址. InetAddress类没有构造方法,所以不能直接new出 ...

  7. Java 继承和多态

                                                        Java  继承和多态 Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因 ...

  8. 111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现

    111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现 本文知识点: 继承的实现 说明:因为时间紧张,本人写博客过程中只是对知识点 ...

  9. 「万字图文」史上最姨母级Java继承详解

    摘要:继承是面向对象软件技术中的一个概念.它使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用. 本文分享自华为云社区<「万字图文」史上最姨母级Java继承详解丨[奔跑吧!JAVA] ...

随机推荐

  1. day09总结

    with 上下文管理 # f = open(r"文件路径", mode="rt", encoding="utf-8")# data = f. ...

  2. 解决android studio 文本乱码问题

    下面图片,部分字体,有一些中文字符无法显示,可选择提交保存,立即可看到效果,不喜欢就再换一个合适的字体.

  3. 读《大话设计模式》——应用策略模式的"商场收银系统"(WinForm)

    策略模式的结构 这个模式涉及到三个角色: 环境(Context)角色:持有一个 Strategy 类的引用.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现.此角色给出所 ...

  4. 输入Javac提示不是内部或外部命令怎么办

    首先,我们在电脑上面找到此电脑, 然后右键点击,选择属性.   在属性中,我们找到高级系统设置,点击打开,如图示.   然后在系统设置中,我们可以找到启动和鼓掌恢复,然后点击环境变量,点击打开.   ...

  5. 基于Three.js的全景---photo-sphere-viewer

    以前公司其他几个前端做全景都是用软件生成,由于本人比较懒,不想去折腾那个软件,于是乎就有了下面的事...... 这个是基于three.js的全景插件  photo-sphere-viewer.js  ...

  6. 你有认真了解过自己的“Java对象”吗? 渣男

    对象在 JVM 中是怎么存储的 对象头里有什么? 文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱,有你想要的. 作为一名 Javaer,生活中的我们可能暂时没有对象,但 ...

  7. 德布鲁因序列与indexing 1

    目录 写在前面 标记left-most 1与right-most 1 确定位置 德布鲁因序列(De Bruijn sequence) 德布鲁因序列的使用 德布鲁因序列的生成与索引表的构建 参考 博客: ...

  8. Python Ethical Hacking - BACKDOORS(7)

    Handling Errors: If the client or server crashes, the connection will be lost. Backdoor crashes if: ...

  9. less : 写一个display:flex的mixin

    和scss一样,less也是一个好用的css预处理语言,语法也很相近. 而我们在使用display:flex的时候,很容易苦恼于里面的设置的单词很难记(尤其是对我这种英语很差的人来说). 所以我们可以 ...

  10. 如何获取json某一级节点的数据

    如何获取json某一级节点的数据 最近做项目有获取和设置固定格式某一级节点值的需求.但是要一级一级地取对于多级的结构来说代码过于冗余且重复,于是写了个递归的方法根据json路径完成值的定点操作.废话不 ...