初识继承以及抽象类

来源:互联网 发布:ubuntu 16.04 samba 编辑:程序博客网 时间:2024/06/06 10:00

继承

什么是继承

继承是面向对象的第二个特征

继承的定义

  • 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
  • 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。
  • 如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来的。在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类。
    (简而言之,java中不支持多继承,但是支持多重继承)

如何实现继承

在java语言中继承使用关键字extends来建立关系。

//从形状类中派生出矩形类
public class Rect extends Shape{
}
//从矩形类中派生出正方形类
public class Square extends Rect{
}

java术语

  • 父类,超类: 继承关系中,被继承的类称为超类(SuperClass),也有叫做父类;其他语言中也有叫基类。
  • 子类,派生类: 继承关系中,继承的类称为子类,也叫派生类。

Java中继承的特点

  • Java只支持单一继承,但可以多层继承(多继承会导致调用的不确定性)
  • 子类不能继承父类private属性和方法
  • 子类不能继承父类的构造方法,但是可以通过super去访问
  • super关键字和子类方法中访问变量
  • super代表父类的一个标识,权且当作父类对象一个引用,可以使用该关键字调用父类的非私有属性和非私有方法。
  • 当我们直接访问变量时,依据就近原则处理。

先在子类方法的局部范围找,有就使用。
若没有,再在子类的成员范围找,有就使用。
若没有,在父类的成员范围找,有就使用。

何时该使用继承

发现两个类的关系是 IS-A ,一个对象是另一个对象的一个分类。

Object

  • Object类是所有Java类的祖先。每个类都使用Object作为超类。所有对象(包括数组)都实现这个类的方法。
  • 在不明确给出超类的情况下,Java会自动把Object作为要定义类的超类。
  • 可以使用类型为Object的变量指向任意类型的对象。(多态)
  • Ojbect中包含所有类都有的方法,比如equals和toString方法。

继承带来的好处

  • 继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。
  • 继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的复用性。
  • 继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。

继承带来的疑问

继承中的构造方法

  • 在继承过程中,子类继承了父类的非私有方法和非私有属性,那么构造方法也继承了吗?
    在Java中,子类的构造过程中,必须调用其父类的构造函数(super()),是因为有继承关系存在时,子类要把父类的内容继承下来。
  • 通过什么手段做到的?
    当你new一个子类对象的时候,必须首先要new一个父类的对像出来,(子类构造函数的第一行必须是super()即调用父类的构造函数)这个父类对象位于子类对象的内部,所以说,子类对象比父类对象大,子类对象里面包含了一个父类的对象,这是内存中真实的情况.构造方法是new一个对象的时候,必须要调的方法,这是规定,要new父类对象出来,那么肯定要调用其构造方法,所以:
    1. 第一个规则

子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法,所谓默认的构造方法,就是没有
参数的构造方法,但是如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是在子类构造方法中我们并没有显示的调用基类的构造方法,就是没写,如:super();并没有这样写,但是这样就会调用父类没有参数的构造方法,如果父类中没有没有参数的构造方法就会出错。


  1. 第二个规则:

如果子类的构造方法中没有显示的调用基类构造方法,则系统默认调用基类
无参数的构造方法注意:如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有默认无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数。

数据初始化顺序:父类成员>父类构造方法>子类成员>子类构造方法

重写

  • 在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
  • 若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
必须注意,子类方法的访问修饰权限不能严于父类;

重载和重写的区别

  1. 重写需要方法名,返回值,参数列表完全相同,重载需要方法名相同,参数列表不同,可以有不同的返回值
  2. 重写访问权限必须大于父类,而重载不做要求。
  3. 重写发生在子类与父类之间,而重载发生在本类中。

抽象类与抽象方法

  • 在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的。如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类
  • 比如new Animal(),我们都知道这个是产生一个动物Animal对象,但是这个Animal具体长成什么样子我们并不知道,它没有一个具体动物的概念,所以他就是一个抽象类,需要一个具体的动物,如狗、猫来对它进行特定的描述,我们才知道它长成啥样。在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以**用以表征抽象概念的抽
    象类是不能实例化的**。

抽象类使用 abstract 关键字完成

如:

 public abstract class Animal{ } ```java中的抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。如:

publc abstract void eat();

“`

使用抽象类和抽象方法时必须注意

  • 抽象方法必须放在抽象类中。
  • 抽象类不能用new实例化对象
  • 抽象方法必须由子类来进行重写。
  • 只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
  • 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
  • 子类中的抽象方法不能与父类的抽象方法同名。
  • abstract不能与final并列修饰同一个类。(因为用final修饰的类不能被继承,而抽象方法必须被继承才能创建实例,不然这个类就没有存在的意义,所以这二者矛盾)
  • abstract 不能与private、static、final或native并列修饰同一个方法。
原创粉丝点击