java7-3 继承
1、继承概述:
把多个类中相同的内容给提取出来定义到一个类中。
如何实现继承呢?
Java提供了关键字:extends
格式:
class 子类名 extends 父类名 {}
父类也称为基类、超类;子类也称为派生类
好处:
A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类之间产生了关系,是多态的前提
而类与类产生了关系,其实也是继承的一个弊端:
类的耦合性增强了。
开发的原则:低耦合,高内聚。
耦合:类与类的关系
内聚:就是自己完成某件事情的能力
1、例子
//使用继承前
/*
class Student {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Teacher {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
*/
//使用继承后
class Person {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Student extends Person {}
class Teacher extends Person {}
class ExtendsDemo {
public static void main(String[] args) {
Student s = new Student();
s.eat();
s.sleep();
System.out.println("-------------");
Teacher t = new Teacher();
t.eat();
t.sleep();
}
}
2、Java中继承的特点:
A:Java只支持单继承,不支持多继承。
有些语言是支持多继承,格式:extends 类1,类2,...
B:Java支持多层继承(继承体系)
/*
class Father {}
class Mother {}
class Son exnteds Father {} //正确的
class Son extends Father,Mother {} // 错误的
*/
class GrandFather {
public void show() {
System.out.println("我是爷爷");
}
}
class Father extends GrandFather {
public void method(){
System.out.println("我是老子");
}
}
class Son extends Father {}
class ExtendsDemo2 {
public static void main(String[] args) {
Son s = new Son();
s.method(); //使用父亲的
s.show(); //使用爷爷的
}
}
3、继承的注意事项:
A:子类只能继承父类所有非私有的成员(成员方法和成员变量)
B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
C:不要为了部分功能而去继承
class A {
public void show1(){}
public void show2(){}
}
class B {
public void show2(){}
public void show3(){}
}
//我们发现B类中出现了和A类一样的show2()方法,所以,我们就用继承来体现
class B extends A {
public void show3(){}
}
这样其实不好,因为这样你不但有了show2(),还多了show1()。
有可能show1()不是你想要的。
那么,我们什么时候考虑使用继承呢?
继承其实体现的是一种关系:"is a"。
Person Student Teacher
水果 苹果 香蕉 橘子
采用假设法。
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
class Father {
private int num = 10;
public int num2 = 20;
//私有方法,子类不能继承
private void method() {
System.out.println(num);
System.out.println(num2);
}
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
class Son extends Father {
public void function() {
//num可以在Father中访问private
//System.out.println(num); //子类不能继承父类的私有成员变量
System.out.println(num2);
}
}
class ExtendsDemo3 {
public static void main(String[] args) {
// 创建对象
Son s = new Son();
//s.method(); //子类不能继承父类的私有成员方法
s.show();
s.function();
}
}
4、类的组成:
成员变量:
构造方法:
成员方法:
而现在我们又讲解了继承,所以,我们就应该来考虑一下,类的组成部分的各自关系。
继承中成员变量的关系:
A:子类中的成员变量和父类中的成员变量名称不一样,这个太简单。
B:子类中的成员变量和父类中的成员变量名称一样,这个怎么玩呢?
在子类方法中访问一个变量的查找顺序:(就近原则)
a:在子类方法的局部范围找,有就使用
b:在子类的成员范围找,有就使用
c:在父类的成员范围找,有就使用
d:如果还找不到,就报错。
class Father {
public void show() {
System.out.println("show Father");
}
}
class Son extends Father {
public void method() {
System.out.println("method Son");
}
public void show() {
System.out.println("show Son");
}
}
class ExtendsDemo4 {
public static void main(String[] args) {
//创建对象
Son s = new Son();
s.show();
s.method();
//s.fucntion(); //找不到符号
}
}
}//结果是: show Son methor Son //名字一样,如果子类中有,先调子类
5、 我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?
我还想要输出父类成员范围的num。怎么办呢?
如果有一个东西和this相似,但是可以直接访问父类的数据就好了。
恭喜你,这个关键字是存在的:super。
this和super的区别?
分别是什么呢?
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
怎么用呢?
A:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
B:调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
C:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
class Father {
public int num = 10;
}
class Son extends Father {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
class ExtendsDemo5 {
public static void main(String[] args) {
Son s = new Son();
s.show();
}
}
6、继承中构造方法的关系
A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
B:为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
注意:子类每一个构造方法的第一条语句默认都是:super();
class Father {
int age;
public Father() {
System.out.println("Father的无参构造方法");
}
public Father(String name) {
System.out.println("Father的带参构造方法");
}
}
class Son extends Father {
public Son() {
//super();这个不写都默认有
System.out.println("Son的无参构造方法");
}
public Son(String name) {
//super();这个不写都默认有
System.out.println("Son的带参构造方法");
}
}
class ExtendsDemo6 {
public static void main(String[] args) {
//创建对象
Son s = new Son();
System.out.println("------------");
Son s2 = new Son("林青霞");
}
}
7、如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错。
如何解决呢?
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化,就出错。
注意事项:
this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
class Father {
/*
public Father() {
System.out.println("Father的无参构造方法");
}
*/
public Father(String name) {
System.out.println("Father的带参构造方法");
}
}
class Son extends Father {
public Son() {
super("随便给");
System.out.println("Son的无参构造方法");
//super("随便给");
}
public Son(String name) {
//super("随便给");
this();
System.out.println("Son的带参构造方法");
}
}
class ExtendsDemo7 {
public static void main(String[] args) {
Son s = new Son();
System.out.println("----------------");
Son ss = new Son("林青霞");
}
}
8、方法重写:子类中出现了和父类中方法声明一模一样的方法。
方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
子类对象调用方法的时候:先找子类本身,再找父类。
方法重写的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
案例:
A:定义一个手机类。
B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
按照我们基本的设计,我们把代码给写出来了。
但是呢?我们又发现新手机应该是手机,所以,它应该继承自手机。
其实这个时候的设计,并不是最好的。
因为手机打电话功能,是手机本身就具备的最基本的功能。
所以,我的新手机是不用在提供这个功能的。
但是,这个时候,打电话功能就没有了。这个不好。
最终,还是加上这个功能。由于它继承了手机类,所以,我们就直接使用父类的功能即可。
那么,如何使用父类的功能呢?通过super关键字调用
class Phone1{
public void show(String name){
System.out.println("给"+name+"打电话");
}
}
class Phone2 extends Phone1{
public void show(String name){
super.show(name);// 继承Phone1类的show方法,
//System.out.println("给"+name+"打电话");
System.out.println("还可以发短信");
}
}
class ExtendsDemo1{
public static void main(String[] args){
new Phone2().show("阿三");
}
}
9、方法重写的注意事项
A:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
B:子类重写父类方法时,访问权限不能更低。就是子类的方法权限不能比父类的低。
最好两者一致。
C:父类静态方法,子类也必须通过静态方法进行重写
其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
子类重写父类方法的时候,最好声明一模一样。
java7-3 继承的更多相关文章
- java-7继承
请自行编写代码测试以下特性(动手动脑):在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. public class QWE { public void main(String[] ...
- java7笔记
1 switch case 增加字符串类型,原理根据字符串hashcode以及string.equal比较2 数值字面量改进 新增二进制数值字面量 0b000004,在数值中间新增下划线方便阅读200 ...
- Java7并发编程实战(一) 守护线程的创建和运行
Java里有一种特殊的线程叫做守护(Daemon)线程,这种线程的优先级很低,通常来说,当一个应用程序里面没有其他线程运行的时候,守护线程才运行,当线程是程序中唯一运行的线程时,守护线程执行结束后,J ...
- Java5、Java6、Java7的新特性
Java5 Java 5添加了8个语言特性:泛型,类型安全枚举,注解,自动装箱和拆箱,增强的循环,静态导入,可变参数,协变返回类型. 1.泛型 Generics: 引用泛型之后,允许指定集合里元素的类 ...
- java5、java6、java7、java8的新特性
Java5: 1.泛型 Generics: 引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处. Parameterized Type作为参数 ...
- JavaSE复习_3 继承
△先默认初始化,在显示初始化,在构造函数初始化 △继承的弊端:代码的耦合性增加了. △子类不能继承父类的构造方法. △子类会拥有父类的私有成员变量,但是必须通过get,set方法访问. △super不 ...
- java7新特新(一) Try-with-resources (TWR)
Try-with-resources (TWR) 在处理IO的代码中,我们会使用大量的try...catch()...finally...语法,其中会在finally进行IO的close操作,写过py ...
- ConcurrentHashMap 从Java7 到 Java8的改变
一.关于分段锁 集合框架很大程度减少了java程序员的重复劳动,然而,在Java多线程环境中,以线程安全的方式使用集合类是一个首先考虑的问题. 越来越多的程序员了解到了ConcurrentHashMa ...
- Java7 和 Java8 中的 ConcurrentHashMap 原理解析
Java7 中 ConcurrentHashMap ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些. 整个 ConcurrentHash ...
- Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了 ...
随机推荐
- LinQ实战学习笔记(四) LINQ to Object, 常用查询操作符
这一篇介绍了下面的内容: 查询object数组 查询强类型数组 查询泛型字典 查询字符串 SelectMany 索引 Distinct操作符 排序 嵌套查询 分组 组连接 内连接 左外连接 交叉连接 ...
- chenxi的js学习笔记
1.本文主体源自:http://www.cnblogs.com/coco1s/p/4029708.html,有兴趣的可以直接去那里看,也可以看看我整理加拓展的. 2.js是一门什么样的语言及特点? j ...
- 如何解决div层被flash遮盖的问题
页面构建中的Flash层会遮挡Div的问题,一般通过设置wmode="transparent" 或wmode="window"就可以解决.不过对于Flash视频 ...
- 网站防止CC攻击的方法
CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,也是一种常见的网站攻击方法,攻击者通过代理服务器或者肉鸡向向受害主机不停地发大量数据包,造成对方服务器资源耗尽,一 ...
- https和http
今天登网站的时候用https登的,没登上去用http找到网站了,于是就去百度了下他俩的区别简单的画了俩图.
- Android中方便好用的倒计时类
一.使用api提供的类进行操作 Android提供了CountDownTimer来让我们进行倒计时,可以让我们很方便的进行倒计时的操作.使用方式也很简单,下面直接贴代码就好了: package ...
- OC中NSArray
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...
- Service的生命周期&Service绑定方法
服务的生命周期: 一.采用start的方式开启服务 生命周期如下: 开启服务: onCreate()--> onStartCommand() (onStart()过时了)---> onDe ...
- JSP基础--JAVA遇见HTML
1.手工编写第一个WEB应用程序 2.默认访问服务器网页首页欢迎界面是 index.jsp,就是网页链接访问其所在的文件夹目录,不访问这个文件,也会自动访问的.如果这个文件夹目录下没有index.js ...
- Effective Java 35 Prefer annotations to naming patterns
Disadvantages of naming patterns Typographical errors may result in silent failures. There is no way ...