(一)Java定义
官方说法: 继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。(要就全要(继承),不要就算(不继承))。
生活中的继承:
①动物类等
继承需要符合的关系是:is-a,父类更通用,子类更具体。
虽然狗和猫都是属于动物,但是两者的属性和行为上有差别(狗能跑,猫也能跑,狗叫汪汪,猫叫喵),所以子类会具有父类的一般特性也会具有自身的特性。
继承描述的是事物之间的所属关系,这种关系是:is-a
的关系。例如,图中猫属于动物,狗也属于动物。可见,父类更通用或更一般,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。
②家谱等
③
(二)类的继承格式
在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
类的继承格式
class A (父类){
}
class B(子类) extends A {
}
注意:在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
以上不难看出,类B,称为子类、派生类(derived class)、SubClass
类A,称为父类、超类、基类(base class)、SuperClass
关于Java-继承几点需要注意的:
① 子类会继承父类所有的实例变量和实例方法
从类的定义来看,类是一类具有相同特性的事物的抽象描述。父类是所有子类共同特征的抽象描述。而实例变量和实例方法就是事物的特征,那么父类中声明的实例变量和实例方法代表子类事物也有这个特征。
当子类对象被创建时,在堆中给对象申请内存时,就要看子类和父类都声明了什么实例变量,这些实例变量都要分配内存。
当子类对象调用方法时,编译器会先在子类模板中看该类是否有这个方法,如果没找到,会看它的父类甚至父类的父类是否声明了这个方法,遵循
从下往上
找的顺序,找到了就停止,一直到根父类都没有找到,就会报编译错误。所以继承意味着子类的对象除了看子类的类模板还要看父类的类模板。
② 子类不能直接访问父类中私有的(private)的成员变量和方法
子类虽会继承父类私有(private)的成员变量,但子类不能对继承的私有成员变量直接进行访问,可通过继承的get/set方法进行访问。如图所示:
③ 在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”
子类在继承父类以后,还可以定义自己特有的方法,这就可以看做是对父类功能上的扩展。
④ Java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
说明:
子类和父类是一种相对的概念
顶层父类是Object类。所有的类默认继承Object,作为父类。
5、一个父类可以同时拥有多个子类
class A{} class B extends A{} class D extends A{} class E extends A{}6、Java只支持单继承,不支持多重继承
(三)继承的好处(为什么需要继承)
-
继承的出现减少了代码冗余,提高了代码的复用性。
-
继承的出现,更有利于功能的扩展。
-
继承的出现让类与类之间产生了
is-a
的关系,为多态的使用提供了前提。-
继承描述事物之间的所属关系,这种关系是:
is-a
的关系。可见,父类更通用、更一般,子类更具体。
-
注意:不要仅为了获取其他类中某个功能而去继承!----不能选择性地继承父类。
继承的特性:
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)
(四)继承的类型
不同于C语言,java不支持多继承,但支持多重继承。
具体代码如下:
class C {//
//1.属性
String name;//姓名
int age = 1;//年龄
public void show(String nation) {
String yi="你好呀,我是一";
System.out.printf("%s%n", yi);
yi=nation;
System.out.printf("%s%n", yi);
}
public void print()
{
//没有初始化,默认赋初值,int:0 boolean:false String:null
System.out.printf("%d %s%n",this.age,this.name );
}
}
class CC extends C{
//新的属性
int luckymoney;
//新的方法
public void show2( ) {
String er="你好呀,我是二";
System.out.printf("%s%n", er);
}
}
//测试类
class test {
public static void main(String[] args) {
CC p = new CC();
p.show("*****");
p.print();
//给继承的属性赋值
p.name="法外狂徒"; p.age=16;
//调用继承的方法
p.print();
//调用自己的方法
p.show2();
}
}