《Java程序设计基础》 第8章手记Part 1
本章主要内容 Part 1
- 子类的创建 - 在子类中访问父类的成员 - 覆盖父类的方法 - ……
本章主要讲继承、抽象类和接口,这篇博客讲的是继承这一部分。使用实验的代码做例子来说明。
类的继承
类的继承是面向对象的程序设计的一个重要特点,通过继承实现代码的复用,被继承的类称为父类或超类(superclass),由继承得到的类称为子类(subclass)
子类继承父类的成员变量和方法,同时可以修改父类的成员变量或重写父类的方法,还可以添加新的成员变量和方法。 Ps:C语言通过函数实现代码复用,但是函数一经写好,它的功能就已经确定,你修改这个函数会影响到所有已经使用这个函数的代码。了解这点,你就能理解继承这种代码复用机制的优点——可以修改,并且不会影响之前使用该功能的旧代码。
使用继承来组织、设计系统中的类,可以提高程序的抽象程度,使之更能接近人类的思维方式,同时继承也能较好的实现代码复用,提升程序开发效率,降低维护工作量。
Java中有一个名为java.lang.Object的特殊类,所有的类都是直接或间接继承得到的。如果没有指明子类所继承的父类,则默认继承这个特殊的类。
子类的创建
子类的创建方法
Java通过关键字extends实现继承,格式如下:
//Java继承示例
class SubClass extends SuperClass
{
...
}
C#实现继承的方式则没有使用任何关键字,而是通过英文分号实现的。
//C#继承示例
public class SubClass : SuperClass
{
}
实验8-1
class PersonB {
String name;
int age;
PersonB() {
name = "Steve Wang";
age = 20;
}
PersonB(String name, int age) {
this.name = name;
this.age = age;
}
void show() {
System.out.println(name+ " " +age);
}
}
class StudentB extends PersonB {
StudentB() {
name = "Zark Berg";
age = 23;
}
StudentB(String name, int age){
this.name = name;
this.age = age;
}
void show(){
System.out.println(name+ " " +age);
}
}
class Inherite {
public static void main(String[] args) {
PersonB a = new PersonB("apple",18);
StudentB b = new StudentB("pear",16);
a.show();
b.show();
}
}
说明: 1. 通过extends关键字,可将父类的成员继承给子类,在使用这些继承过来的成员时,可利用过去的语法即可。 2. Java程序在执行子类的构造方法之前,会先调用父类中没有参数的构造方法,其目的是为了帮助父类继承自父类的成员做初始化操作。
调用父类中特定的构造方法
即使程序中没有指明子类调用父类的构造方法,运行时也会默认代用父类中没有参数的构造方法。如果父类中有多个构造方法,则使用super关键字来调用特定的构造方法。this这里指代的是父类构造方法名称。
例: super(String a, int b)
将调用父类中有2个参数,并且第一个是字符串类型,第二个是整型的构造方法。
你需要阅读原书p123页到p123页的内容来具体了解super及super和this的关系。
在子类中访问父类的成员 也是使用super关键字,格式如下
super.变量名
super.方法名
需要说明的是,父类中的成员必须不是private,才能被子类访问,建议使用protected,使用public会降低封装性。
覆盖
覆盖(Overriding)的概念与重载类似,都是Java“多态”的实现方法。覆盖是指在子类中,定义名称、参数个数和类型均与父类完全相同的方法,用来重写父类中同名方法的操作。C#的覆盖是通过虚方法实现的,具体参见之前的博文《C#多态》。
覆盖父类的方法
实验8-2
class Animal {
String name;
Animal() {
name = "Animal";
}
void play() {
System.out.println(name);
}
}
class Bird extends Animal {
String name;
Bird() {
name = "Bird";
}
void play() {
System.out.println(name);
}
}
class Fish extends Animal {
Fish() {
name = "Fish";
}
void play() {
System.out.println(name);
}
}
class Override {
public static void main(String[] args) {
Animal a = new Animal();
Bird b = new Bird();
Fish c = new Fish();
a.play();
b.play();
c.play();
Animal a1 = new Bird();
Animal a2 = new Fish();
a1.play();
a2.play();
}
}
用父类的对象访问子类的成员
Java中可以用父类的对象访问子类的成员,这体现了“父亲的行为像儿子,而不是儿子的行为像父亲”这种面向对象编的程思想。 注意: 父类的对象访问子类的成员仅限于“覆盖”发生时,如果子类没有覆盖父类的方法,则不能父类对象不能访问子类成员。
不可被继承的成员或最终类
默认情况下所有的成员变量和方法都可以被覆盖,如果不希望被覆盖,则需加final关键字做声明。
例:static final double PI = 3.1415926
例:public final void show()
final修饰成员变量,则说明该成员变量是最终量,即常量,程序的其他部分可以访问但不能修改。
final修饰成员方法,则该方法为最终方法,不能被子类所覆盖。
知乎:Solo | 微博@从流域到海域
- 大数据算法设计模式(2) - 左外链接(leftOuterJoin) spark实现
- hs_err_pid
- django celery的分布式异步之路(二) 高并发
- django celery的分布式异步之路(一) 起步
- SpringMVC拦截器Interceptor
- 元宵快乐:看SQL大师们用SQL绘制的团圆
- Python Redis pipeline操作
- python concurrent.futures
- Deepmind的星际争霸2强化学习教程(1):建立环境与训练模型
- python contextlib 上下文管理器
- Django扩展自定义manage命令
- Elasticsearch分片、副本与路由(shard replica routing)
- EsRejectedExecutionException排错与线程池类型
- python重试(指数退避算法)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- iOS13 关闭黑暗模式+状态栏显示问题解决方法
- 0807-6.2.0-CDSW中Session列表和team分析
- 单细胞转录组基础分析八:可视化工具总结
- 单细胞转录组基础分析七:差异基因富集分析
- 定位权限请求时易犯的错误小结
- NSOperationQueue队列中操作依赖相关思考
- 单细胞转录组高级分析一:多样本合并与批次校正
- 10元最多可喝多少瓶啤酒?(不可借酒+可借酒,swift语言实现)
- 单细胞转录组高级分析二:转录调控网络分析
- 关于数组内元素是否会被改变的思考
- 排序之选择排序实现(swift)
- 去除友盟等第三方SDK失败的解决办法(clang: error: no such file or directory:xx)
- iOS踩坑之多代理模式使用注意
- 单细胞转录组高级分析三:细胞通讯分析
- 单细胞转录组高级分析四:scRNA数据推断CNV