一:什么是面向对象的继承
- 当A继承B时,A是B的子类,B是A的父类
- 单继承:一个子类只能有一个直接的父类
- 多继承:一个子类可以有多个直接的父类
- java只继承单继承,不支持多继承(因为多继承会产生调用的不确定性—多个父类中有相同的成员)
继承的案例
class Fu{
int num1=4;
}
class Zi extends Fu{
int num2=5;
void show(){
System.out.println(num2+"...."+num1);
}
}
class ExtendsDemo2{
public static void main(String[] args){
Zi z=new Zi();
z.show();
}
}
二:继承的好处
- 提高代码的复用性
- 让类与类之间产生关系,给第三特征提供前提(没有继承就没有多态)
三:什么时候定义继承
- 当类与类之间存在所属关系就定义继承
- xxx是yyy一种 (xxx extends yyy)
- 但是不能够为了继承而去继承,如下
class A{
void show1(){}
void show2(){}
}
class B{
void show1(){}
void show3(){}
}
A与B类中都有show1();但是不可以去继承,因为A中有show2(),但B中没有,所以不需要继承。如果非要继承就单独定义show1();
所以不可以乱继承。
class Person{
String name;
int age;
}
class Student extends Person{
//String name;
//int age;
void study(){
System.out.println(name+"...student study..."+age);
}
}
class Worker extends Person{
//String name;
//int age;
void work(){
System.out.println("Worker work");
}
}
class ExtendsDemo{
public static void main(String[] args){
Student s=new Student();
s.name="wang";
s.age=20;
s.study();
}
}
四:在继承里,子父类成员特点
1.成员变量
- 当本类成员与局部变量成员同名时,用this区分,this代表本类本类对象的引用
- 当子父类成员变量同名时,用super区分,super代表父类的空间
2.成员函数
-当子父类出现成员函数一模一样时,会运行子类函数
-出现此情况称为覆盖操作
-覆盖操作后父类特征
1)重载,同一个了自己类中,overload
2)覆盖,子类中 覆盖也称为重写,覆写override
3.构造函数
class Fu{
Fu(){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();调用父类中的空参数构造函数
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
**1.**在子类构造函数时,发现访问子类构造函数时父类也运行了
为什么?
因为在子类的构造函数中的第一行有一个默认的隐式语句 super();
class Demo{
super();
return;
}
2.构造中不是空参
class Fu{
Fu(int x){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
修改方法如下:
子类实例化过程:子类中所有构造函数都会去访问父类中空参数构造函数
class Fu{
Fu(int x){
System.out.println("fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
super(2);
System.out.println("zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi();
}
}
五:覆盖的注意事项
- 子类方法覆盖父类方法时,子类权限应该大于等于父类权限
- 满足大于等于父类条件才可以覆盖
- 静态只能覆盖静态,或者被静态覆盖
- 目前我所学的权限,public ,private,默认权限
覆盖案例
class Fu{
void show(){
System.out.println("fu run show");
}
}
class Zi extends Fu {
public void show(){
System.out.println("zi run show ");//子类覆盖父类的函数
}
}
class ExtendsDemo3{
public static void main(String [] args){
Zi z=new Zi();
z.show();
//z.show2();
NewPhone p=new NewPhone();
p.newShow();
}
}
class Phone{
void call(){}
void show(){
System.out.println("number");
}
}
class NewPhone extends Phone{
void newShow(){
System.out.println("name");
System.out.println("pic");
//System.out.println("number");
super.show();//用super代表父类的number
}
}
六:什么时候使用覆盖
当一个类进行子类扩展时,子类需要保留父类的功能声明,但是要定义子类中该功能特有内容,就使用功能覆盖操作完成
七:子父类中的构造函数中的实例过程
- 子类实例化过程:子类中所有构造函数都会去访问父类中空参数构造函数
- 为什么子类实例化的时候要访问父类的构造函数?
- 因为子类继承父类,获取父类中的内容(属性),所以使用父类内容之前,要先看父类是如何对自己的内容进行初始化的
- 为什么子类必须访问父类后,就在子类构造函数中加入了super()语句?
- 如果父类没有定义父类空参数构造函数,则子类函数就必须用super()语句明确调用的父类中那个构造函数,,若子类中用this调用本类构造函数时,super就没有用了。因为super与this都只能定义在第一行,(父类的初始化要先完成)只能存在一个。 但是,子类中肯定有其他构造函数访问父类 的构造函数
class Fu{
Fu(){
System.out.println("A fu run");
}
Fu (int x){
System.out.println(" B fu run");
}
}
class Zi extends Fu{
Zi(){
//super();diaoyongfuleikongcanshu
//super(2);
System.out.println("C zi run");
}
Zi (int x){
System.out.println("D zi run");
}
}
class ExtendsDemo4{
public static void main(String[] args){
new Zi(4);
}
}
class Fu{
Fu(){
super();
show();
return;
}
void show(){
System.out.println("fu show");
}
}
class Zi extends Fu{
int num=8;
Zi(){
super();
return;
}
void show(){
System.out.println("zi show......."+num);
}
}
class ExtendsDemo5{
public static void main(String [] args){
Zi z=new Zi();
z.show();
}
}