java继承程序代码_Java面向对象编程-继承

第六章 继承

6.1 继承的基本语法

在Java语言中,用extends关键字来表示一个类继承了另一个类。

public class Sub extends Base{

...

}

以上的代码表明Sub类继承类Base类。

当Sub类和Base类位于同一个包中时,Sub类继承Base类中public、protected和默认访问级别的成员变量和成员方法。

当Sub类和Base类位于不同的包中时,Sub类继承Base类中public、protected访问级别的成员变量和成员方法。

Java语言不支持多继承,即一个类只能直接继承一个类。

尽管一个类只能有一个直接父类,但是它可以拥有多个间接的父类。

所有的Java类都直接或间接的继承了java.lang.Obiect类,Object类是所有Java类的祖先。在这个类中定义了所有的Java对象都具有的相同行为。

6.2 方法重载

有时候,类的同一种功能有多种实现方式,到底采用哪种实现方式,取决于调用者给定的参数。

对于类的方法(包括从父类继承的方法),如果有两个方法的方法名相同,但参数不一致,那么可以说,一个方法是另一个方法的重载。

重载方法必须满足以下条件:

方法名相同

方法的参数类型、个数、顺序至少有一项不同。

方法的返回类型可以不同。

方法的修饰符可以不相同。

在一个类中,不允许定义两个方法名相同,并且参数签名也相同的方法。

6.3 方法覆盖

如果在子类中定义的一个方法,其名称、返回类型及参数签名正好与父类中的某个方法的名称、返回类型及参数签名相匹配,那么可以说,子类的方法覆盖了父类的方法。

覆盖必须满足多种约束:

子类的名称、参数签名和返回类型必须与父类的名称、参数签名和返回类型一致。

子类方法不能缩小父类方法的访问权限。

子类方法不能抛出比父类方法更多的异常。

方法覆盖只存在于子类和父类(包括直接父类和间接父类)之间。

父类的静态方法不能被子类覆盖为非静态方法。

子类可以定义同父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。

父类的非静态方法不能被子类覆盖为静态方法。

父类的私有方法不能被子类覆盖。

父类的抽象方法可以被子类通过两种途径覆盖:一是子类实现父类的抽象方法,二是子类重新声明父类的抽象方法。

父类的非抽象方法可以被覆盖为抽象方法。

6.4 方法覆盖与方法重载的异同

方法覆盖和方法重载具有以下相同点:

都要求方法同名

都可以用于抽象方法和非抽象方法之间

方法覆盖和方法重载具有以下不同点:

方法覆盖要求参数签名必须一致,而方法重载要求参数签名必须不一致。

方法覆盖要求返回类型必须一致,而方法重载对此不作限制。

方法覆盖只能用于子类覆盖父类的方法,方法重载用于同一个类的所有方法(包括从父类中继承而来的方法)

方法覆盖对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。

父类的一个方法只能被子类覆盖一次,而一个方法在所在的类中可以被重载多次。

6.5 super关键字

super和this关键字都可以用来覆盖Java默认作用域,使被屏蔽的方法或变量变为可见。

在以下场合会出现方法或变量被屏蔽的现象:

在一个方法内,当局部变量和类的成员变量同名,或者局部变量和父类的成员变量同名时,按照变量的作用域规则,只有局部变量在方法内可见。

当子类的某个方法覆盖了父类的一个方法时,在子类的范围内,父类的方法不可见。

当子类中定义类和父类同名的成员变量时,在子类的范围内,父类的成员变量不可见。

注意:如果父类的成员变量和方法被定义为private类型,那么子类永远无法访问它们。

在程序中,super关键字在以下情况下会被使用:

在类的构造方法中,通过super语句调用这个类的父类的构造方法

在子类中访问父类的被屏蔽的方法和属性。

注意:只能在构造方法或实例方法内使用super关键字,而在静态方法和静态代码块中不能使用super关键字

6.6 多态

当系统A访问系统B的服务时,系统B可以通过多种实现方式来提供服务,而这一切对系统A是透明的。

Java语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。

如果把引用变量转换为子类类型,称为向下转型;如果把引用变量转换为父类类型,称为向上转型。

多态的特性:

对于一个引用类型的变量,Java编译器按照它声明的类型来处理。

Java编译器允许具有直接或间接继承关系的类之间进行类型转换,对于向上转型,不必使用强制类型转换;对于向下转型,必须使用强制类型转换。

假如两种类型之间没有继承关系,即不在继承树的同一个继承分支上,那么Java编译器不允许进行类型转换。

对于一个引用类型的变量,运行时Java虚拟机按照它实际引用的对象来处理。

在运行时,子类的对象可以转换为父类类型,而父类的类型实际上无法转换为子类类型。

在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:

实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的。

静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定。

成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上在编译阶段就已经做了绑定。

6.7 继承的利弊和使用原则

6.7.1 继承树的层次不可太多

继承树的层次(不考虑顶层的Object类)应当尽量保持在2~3层。如果继承树的层次很多会导致以下弊端:

对象模型的结构太复杂,难以理解,增加了设计和开发的难度。

影响系统的可扩展性。

6.7.2 继承树的上层为抽象层

当一个系统使用一棵继承树上的类时,应该尽可能把引用变量声明为继承树的上层类型,这可以提高两个系统之间的松耦性。

位于继承树上层的类具有以下作用:

定义了下层子类都拥有的相同属性和方法,并且尽可能地为多数方法提供默认的实现,从而提高程序代码的可重用性。

代表系统的接口,描述系统所能提供的服务。

6.7.3 继承关系最大的弱点:打破封装

继承关系最大的弱点就是打破了封装。增加了维护软件的工作量。还会导致父类的实现细节被子类恶意篡改的危险。

6.7.4 精心设计专门用于被继承的类

对这些类必须提供良好的文档说明,使得创建该类的开发人员知道如何正确安全的扩展它。

尽可能封装父类的实现细节,也就是把代表实现细节的属性和方法定义为private类型。

把不允许子类覆盖的方法定义为final类型。

父类的构造方法不允许调用可被子类覆盖的方法。

如果某些类不是专门为了继承而设计的,那么随意继承它们是不安全的,可以采用以下两种措施来禁止继承。

把类声明为final类型。

把这个类所有构造方法声明为private类型,然后通过一些静态方法来负责构造自身的实例。

6.7.5 区分对象的属性与继承

6.8 比较组合与继承

组合关系

继承关系

局部类

父类

整体类

子类

从整体类到局部类的分解过程

从子类到父类的抽象过程

从局部类到整体类的组合过程

从父类到子类的扩展过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值