继承:类的继承通过关键字extends来实现
其格式: class 子类名 extends 父类名
class Fu
{
类体
}
class Zi extends Fu
{
类体
}
class RunDemo
{
public static void main()
{
主函数
}
}
Java中的继承:Java中只支持单继承,不支持多继承。
为什么那?
因为多继承存在安全隐患:当多个父类中定义了相同的功能。当功能的内容不同时,子类对象不确定要运行哪一个,但是java保留这种机制,并用另一种体现形式来表示(也就是接口的实现),多实现。
java支持多层继承,也就是一个继承体系
如何使用一个继承体系中的功能哪?
想要使用的体系,县查阅体系父类的描述,因为父类中定义的时该体系中共性的功能。通过了解共性功能可以知道该体系的基本功能。
那么在具体调用时,要创建最子类的对象,为什么?
一是因为有可能父类不能创建对象(比如父类是抽象的)
二是因为创建子类对象可以使用更多的功能,包括父类的也包括子类特有的。
下面我们谈一谈子父类中成员的特点
类中的成员有:
1.变量 2.函数 3.构造函数
一、子父类中的变量:
如果子父类中出现同名的非私有变量时,子类要访问本类的这个同名变量,用this关键字。子类要访问父类中的同名变量,用supper关键字。
例如:
class Fu
{
int num = 4;
}
class Zi extends Fu
{
int num = 5;
//定义一个访问父类num的函数
void showFu()
{
System.out.println(super.num);
}
//定义一个访问子类num的函数
void showZi()
{
System.out.println(this.num);
}
}
class RunDemo
{
public static void main(String[] args)
{
//创建子类对象
Zi z = new Zi();
//子类对象调用子类方法
z.showFu();
z.showZi();
}
}
/*
运行结果:
4
5
*/
二、子父类中的函数
子父类中的函数:
当子类中存在与父类中一模一样的函数时(函数名与函数参数列表一样时),子类对象调用这个名字的函数时,会运行子类函数的内容。如同父类的函数被覆盖一样。
这种情况是子父类中函数的一个特性:重写(覆盖)
什么时候用到重写?
当子类继承父类,沿袭了父类的功能到子类中,但是子类也具备该功能,但是功能内容却和父类的不一致,这时没有必要定义新功能,而是使用重写特性,保留父类的功能定义,并重写该功能内容。
覆盖的注意事项:
1.子类函数覆盖父类函数,必须保证子类函数的权限大于等于父类权限才能实现覆盖,不然编译失败。
2.静态函数只能覆盖静态函数
覆盖与重载的区别:
重载:只看同名函数的列表
覆盖:子类与父类的方法名与参数列表要完全一致
三、子父类中的构造函数
在对子类对象初始化时,父类的构造函数也会运行。那是因为子类的构造函数中默认第一行有一条隐式的语句 super();
super():会访问父类中的空参数构造函数,而且子类中所有的构造函数默认第一行都会有“super();”语句。
为什么子类一定要访问父类中的构造函数?
因为父类中的数据。子类可以直接获取。所以子类对象在建立时。需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super语句只能定义在子类构造函数的第一句
结论:
子类的所有的构造函数默认都会访问父类中的空参数的构造函数。因为子类的构造函数中默认第一行有一条隐式的语句 super();
当父类中没有空参数的构造函数时(父类中的构造函数被重写并赋予了参数),这时子类构造函数要访问父类构造函数需要改写默认的super()语句的参数来访问指定的父类构造函数。
当然:子类中的构造函数要访问本类的其他构造函数,也可以在构造函数的第一行(这个第一行要么写super语句要么写this语句,这两个语句不能同时存在第一行)用this语句来访问本类的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
继承的好处与弊端
好处:
提高了代码的复用性
提高了代码的可维护性
是多态的前提
弊端:
提高了代码的耦合性
耦合性:事物与事物之间的依赖关系,互相影响的程度
开发原则:面向对象最终要实现的目的
高内聚(一个对象自己可以完成各种事情)、低耦合(对于其他代码的依赖性非常低)
代码的复用性高
继承的注意事项:
- 私有的成员不能被继承
父类中有一些私有成员,不能在子类中直接使用
其实在子类对象中,仍然包含了父类中定义的私有成员变量
只不过在子类中,不能直接访问父类中定义的私有成员变量
- 父类中的构造方法,不能继承
原因:
父类的构造方法需要和父类的类名一致、子类的构造方法需要和子类类名一致,父 类和子类的类名不一样。因此无法继承,名称有冲突。
父类的构造方法用于给父类的成员变量赋值,子类的构造方法用于给子类的成员变 量赋值,子类的成员变量较多,使用父类的构造方法无法将子类中所有的成员 变量都进行赋值,因此不继承父类的构造方法。
解决:
子类不继承父类的构造,但是可以【调用】父类的构造方法。