一文打尽Java继承的相关问题
相关文章:
- 《面向对象再探究》:介绍了面向对象的基本概念
- 《详解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类有name、age属性和say()方法,Dog类增加了address属性和watchDoor()方法。
2. 概念介绍
在现实生活中有许多继承的例子,比如“子承父业”、“继承父母财产”、“继承某人意志”等,这些都是在强调一个体得到另一个体的东西,他们之间存在“继承关系”。
在Java中,继承是类和类之间的关系。在《面向对象再探究》这篇文章中举了动物Animal类和狗Dog类、猫Cat类、兔子Rabbit类的例子并写了代码,这里直接拿来用不再列出,请移步此文章。
我们可以说狗、猫、兔子是动物,但不可以说动物是狗、猫、兔子。动物普遍有眼睛、耳朵等属性,有跑、吃、叫等行为。狗显然也具有这些属性和行为,但是狗也具有一些它特有的属性和行为,比如灵敏的鼻子、看门等。
在这个例子中,Animal类是父类,Dog类、Cat类、Rabbit类是子类。子类和父类存在继承关系,可以说:子类“是”父类,该关系是继承的一个明显特征。
下面是关于继承的几个Q&A:
Q1: 什么时候需要用到继承?
A1: 个人认为可从以下两点出发:
- 面向对象语言是对现实世界的抽象,所谓“万物皆对象”,那么我们在实际开发中的类肯定都是与现实世界的实物相对应的,所以看实物之间的关系有没有继承关系。
- 当有若干类有大量重复的属性和方法,那么就可以考虑使用继承,将这些重复的属性和方法抽成父类。
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. 子类如何使用父类的私有成员?
子类不继承父类的私有成员,但是如果父类有能访问其私有成员变量的public或protected的方法(比如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()方法,直接访问了name和age属性,如果子类继承了父类的私有成员,那么这样写是没问题的,但事实是name和age报红了,说明子类没有继承父类的私有成员。
虽然子类没有继承父类的私有成员,但是我们可以通过父类的公有方法使用其私有成员变量,代码改动如下:
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继承的相关问题的更多相关文章
- java继承属性相关介绍
这个只需要记住一点,父类的任何属性(变量可以看做属性),子类均可继承并覆盖,allType(father)-->changeAnyType(son)-->AnyType 这是父类的所有代表 ...
- 一文打尽Java抽象类和接口的相关问题
相关文章: <面向对象再探究>:介绍了面向对象的基本概念 <详解Java的对象创建>:介绍了对象的创建.构造器的使用 <一文打尽Java继承的相关问题>:介绍了继承 ...
- Java继承相关知识总结
Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...
- 【Java初探01】——Java简介及相关
Java 简介 java 是一种高级的面向对象的程序设计语言,使用Java语言编写的程序时跨平台的.从pc到手机,都有Java开发的程序和游戏,Java程序可以在任何计算机,操作系统和支持的Java的 ...
- JAVA继承时构造函数的问题
今天看到java继承部分时,关于构造函数是否继承以及如何使用时遇到了点问题,后来查找相关资料解决了. 下面是我个人的总结: 先创建一个父类,里面有两个构造函数: public class Jisuan ...
- 【Socket编程】Java中网络相关API的应用
Java中网络相关API的应用 一.InetAddress类 InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址. InetAddress类没有构造方法,所以不能直接new出 ...
- Java 继承和多态
Java 继承和多态 Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因 ...
- 111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现
111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现 本文知识点: 继承的实现 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
- 「万字图文」史上最姨母级Java继承详解
摘要:继承是面向对象软件技术中的一个概念.它使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用. 本文分享自华为云社区<「万字图文」史上最姨母级Java继承详解丨[奔跑吧!JAVA] ...
随机推荐
- flutter学习01-flutter起步安装配置(window, vscode开发)
从零开始配置flutter环境,如果直接去看官方文档配置的话,太过复杂,其实正式没有那么多步骤,记录一下: 1.首先,前往下面这个网站,下载flutter sdk https://flutter.d ...
- Hangfire实战(一)------Hangfire+SQL Server实现简单的任务调度
Hangfire:一个开源的任务调度框架 开发环境:VS2017,SQL Server 2012,.NET Framework 4.5 项目类型:控制台应用程序 1.在vs的程序包控制台中为项目添加H ...
- JavaWeb基础(day14_css)
css css样式种类 内部样式 在head标签中使用 <style>标签 行内样式 直接在标签中写style属性进行赋值,style属性的就相当于内部样式的{} 外部样式 单独写一个文件 ...
- 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章
前言 当你准备去复习Spring中Bean的生命周期的时候,这个时候你开始上网找资料,很大概率会看到下面这张图: 先不论这张图上是否全面,但是就说这张图吧,你是不是背了又忘,忘了又背? 究其原因在于, ...
- Quartz.Net系列(十六):Misfire策略在SimpleScheduler和CronScheduler中的使用
1.场景 ①因为工作线程都在忙碌,所以导致某些Trigger得不到触发 也就是默认10个工作线程而我有15个Trigger同时触发 这就导致有5个不能被触发,而不幸的是Trigger所关联的Job执行 ...
- Burp Suite Target Module - 目标模块
模块目的之一:获取网站分析 1.从Proxy - HTTP history界面选中需要加入Target Scope的Host 地址,右击,选中Add to Scope. 2.打开Target - Sc ...
- c# Winfrom-DataGridView实现筛选功能
//应对用户需求,需要在DataGridView中直接进行筛选功能,在网上找了一些代码加上自己修改整理过后的类,仅供参考! //上面代码可以直接创建类库项目生成DLL文件,下面代码为另外项目引用创 ...
- C#中的类与对象
类:说白了就是类型,是对具体事物的一种抽象总结. 对象:一个具体的事物. 类与对象的关系,类实例化就会得到一个对象,同样一个对象也应该属于某一个类.例如张三这个人,他是一个对象,同时他属于人类,在程序 ...
- 小程序开发全栈1.2/3/4组件、flex布局、样式
1.2 组件 1.2.1 text组件 编写文本信息,类似于HTTP中的span 1.2.2 view组件 容器,类似于HTTP中的div 1.2.3 image组件 图片显示组件 1.3 页面fle ...
- 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】
可以分别枚举两人正面朝上的次数来统计答案,所求即为 \[\sum_{i=0}^{a}\sum_{j=0}^{b} \binom{a}{i} \binom{b}{j} [i>j] \] 将\(i\ ...