1.为什么需要使用继承?
1.提高代碼的的重用性(减少代码数量)
2.提高程序的扩展性
2.Java继承的语法
Java继承的关键字:extends
格式:
public class 类名 extends 类名 {}
注意:类的继承是单继承;与接口的多继承相区别
现实生活中什么样的关系需要使用继承来实现呢?
包含关系
3.子类继承到了父类的所有的属性和方法。但是能否访问和调用是另一回事。
访问修饰符的可使用性性能表:
访问修饰符 | 同类中 | 同包不同类 | 不同包 | 不同包但是有继承关系的子类中 |
private(私有) | 可以 | 不可以 | 不可以 | 不可以 |
(默认) | 可以 | 可以 | 不可以 | 不可以 |
protected(保护) | 可以 | 可以 | 不可以 | 可以 |
public(公用) | 可以 | 可以 | 可以 | 可以 |
子类是否可以定义父类没有的属性和方法?
可以
4.方法重写(覆盖)
什么情况需要使用方法重写
子类与父类有同名内容不同的方法,则需重写子类的方法。
例如:1、儿子继承了父亲的企业;而父亲有父亲的经营方法,儿子有儿子的经营方法。
2、学生的子类:大、中、小学生。虽然都要学习,但各有不同的学习方法。
方法重写条件:
1、必须要存在继承关系
2、重写方法的访问修饰符可以大于或者等于父类方法的访问修饰符。
3、重写方法的返回值类型、方法名、参数都必须要和父类的一致。
4、方法体不同
重写后的方法是怎样被调用?
new关键字后的构造方法是谁的,如果是子类的那么优先调用子类的方法,如果子类没有才会调用父类的方法。
代码:
Student un = new UNStudent("张三");
若UNStudent类中有:public UNStudent(String name){......}则优先调用UNStudent类的方法
若没有才调用 Student类中的 public Student(String name){......}
5.自动转型
要使用自动转型必须要存在继承关系。
一般为父类向子类转型
格式:
父类名 对象名 = new 子类构造方法(参数值,...);
Student un = new UNStudent();
使用自动转型后:无法调用父类中未定义过的方法。(只能调用父类中定义过的方法)
java在编译时,只考虑对象名的类型;也就是说在编译会将调用的方法去父类中进行查找,如果存在则通过编译,如果不存在则报错。
学校的有英语老师,现在教的是大学生的英语。这位英语老师是否可以教高中生英语呢?
这位英语老师是否可以教初中生英语呢?这位英语老师是否可以教小学生英语呢?
如果学生类型增加到10种?100种?
Student {
study(){}
}
UNStudent extends Student{
study(){}
}
GStudent extends Student{
study(){}
}
CStudent extends Student{
study(){}
}
XStudent extends Student{
study(){}
}
Teacher{
//teach(UNStudent un){un.study();}
//teach(GStudent un){un.study();}
//teach(CStudent un){un.study();}
//teach(XStudent un){un.study();}//这需要定义许多种方法,为编程者带来不便(所以这里舍弃)
-----------------------------------
teach(Student stu){stu.study();}//此处利用自动转型
}
UNStudent un = new UNStudent();
teach(un); // 其过程可理解为:Student stu =new UNStudent(); 父类名 对象名 = new 子类构造方法(参数值,...);
stu=un;
6.多态
(摘自《C++程序设计教程(第二版)》)定义:一个操作随着所传递或捆绑的对象类型的不同能够做出不同的反应的行为模式
多态分两种:
(1)编译时多态(设计时多态):方法重载。
(2)运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。(我们平时说得多的事运行时多态,所以多态主要也是指运行时多态)
如:继承、方法重写、自动转型
运行时多态存在的三个必要条件:
一、要有继承(包括接口的实现);
二、要有重写;
三、父类引用指向子类对象。
7.super关键字
super(参数值,...);
调用父类指定参数的构造方法
super.方法名(参数值,...);
调用父类对应参数的普通方法
无带参构造方法时:
父类如果未出现构造方法,那么子类会默认调用父类中默认的无参构造方法。
如果出现无参的构造方法而无其他带参构造方法,那么子类会默认调用该无参构造方法。
有带参构造方法时: 父类如果没有无参数的构造方法,那么子类必须要使用super(参数值,..)的方式来调用父类的所有带参构造方法。
如果有无参数的构造方法和带参的构造方法,那么子类中只需要有无参构造方法即可(默认的无参构造方法亦可),其他带参构造方法随意加入、修改。
我认为:带参的构造方法是不被继承的方式传递的。而这有可能打破了继承的规则,所以需要程序员用代码把带参的构造方法传递到子类中。
默认的构造方法是什么: Java默认会给类提供一个无参数的构造方法。
即:public Student(){ }
但当一个类中出现了其他的带参构造方法,则java便不会提供无参数的构造方法了。实例化对象是也不能使用无参构造方法。
可以在子类中定义父类中没有的构造方法。
如果子类重写了父类的方法后,还想执行父类的方法,那么可以使用super.方法名(参数值,...),就可以调用到父类被重写的方法。
代码:
父类中有方法:
punlic void study(){
System.out.print("1");
}
子类中的方法:
punlic void study(){
super.study();
System.out.print("2");
}
则执行子类study方法时,输出:12