面向对象03
2018-11-13 本文已影响12人
丫甘九
继承的引用和概述
继承概述
- 多个类中存在相同属性和行为时,将这些内容抽取到单独的一个类中,那么多个类就无需再定义这些属性和行为,只要继承那个类就好了
- 通过extends关键字可以实现类与类的继承
class 子类名 extends 父类名{} - 单独的这个类被称为父类,基类或者超类,这多个类可以称为子类或者派生类
- 有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员
package miangxiangduixiang03;
//定义一个学生类
public class student {
String name;
int age;
public student(){}
//getXxx(){}/setXxx(){}
public void eat(){
System.out.println("吃饭");
}
//定义一个老师类
public class Teacher {
String name;
int age;
public Teacher(){}
//getXxx(){}/setXxx(){}
public void eat(){
System.out.println("吃饭");
}
}
/*观察上面俩个代码,我们发现:
* name,age以及getxxx()和setxxx(),还有eat()都是一样的
* 如果我们后来继续定义类,例:工人类、医生类、军人类他们也具有这样的内容
* 那么,我们每一次定义这样的类的时候,都要把这些重复的内容在定义一遍
* 太麻烦了,所以我们需要改进,但是如何改进呢???
* 解:把这些相同的内容定义到一个独立的类中
* 然后,让这多个类和这个独立的类产生一个关系,有了这个关系后,这多个类就可以具备这独立的类的功能
* 为了这个功能,java就提供了一个技术 继承
* 继承怎么表示呢?继承的格式是怎么样的呢?
* class fu{
* }
* class zi extends fu{
* }
* 我们就回头改我们的代码
*/
public class person{
String name;
int age;
public person(){}
//getXxx(){}/setXxx(){}
public void eat(){
System.out.println("吃饭");
}
}
public class student extends person{
public student();
}
public class Teacher extends person{
public void Teacher() {
}
}
}
继承案例和继承的好处
继承的好处
- 提高了代码的复用性
(多个类相同的成员可以放到一个类中) - 提高了代码的维护性
(如果功能的代码要修改,修改一处即可) - 让类与类产生了关系,是多态的前提
(其实这也是继承的一个弊端,他的耦合性很强)
package miangxiangduixiang03;
//使用继承前
public class student2 {
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
public class Teacher2{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
//使用继承后
public class person2{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
class student2 extends person2{}
class Teacher extends person2{}
}
package miangxiangduixiang03;
import miangxiangduixiang03.student2.Teacher2;
public class student2test {
public static void main(String[] args) {
student2 s = new student2();
s.eat();
s.sleep();
Teacher2 t = new Teacher2();
t.eat();
t.sleep();
}
}
结果都一样
错误,要修改,每个类分开存放
继承的弊端
- 类的耦合性增强
开发的原则:低耦合,高内聚
耦合:类与类的关系
内聚:就是自己完成某件事情的能力
java中类的继承特点
java只继承单继承,不支持多继承
- 一个类只能有一个父类,不可以有多个父类
- class student extends demo{}//ok
- class student extends demo1, demo2//no ok
java 支持多层继承(继承体系)
- class A{}
- class B extends A{}
- class C extends A{}
package miangxiangduixiang03;
public class extendsdemo {
public void show(){
System.out.println("我是爷爷");
}
}
package miangxiangduixiang03;
public class extendsdemoson extends extendsdemo{
public void method(){
System.out.println("我是爸爸");
}
}
package miangxiangduixiang03;
/*public class sonson extends extendsdemo,extendsdemoson {
}
//这种方是错误的,只能单继承
*/
public class sonson extends extendsdemoson {
}
package miangxiangduixiang03;
public class extendsdemotest {
public static void main(String[] args) {
sonson s = new sonson();
s.show();
s.method();
}
}
继承中构造方法的关系
- 子类中所有的构造方法都会默认访问父类中的空参数的构造方法
为什么呢??? - 因为子类会继承父类中的数据,可能还会使用父类中的数据,所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个构造方法的第一条语句默认都是:super()、
package miangxiangduixiang03;
public class father {
int age;
public father(){
System.out.println("这是father的无参构造方法");
}
public father(String name){
System.out.println("这是father的带参构造方法");
}
}
package miangxiangduixiang03;
public class son1 extends father {
public son1(){
super();
System.out.println("这是son的无参构造方法");
}
public son1(String name){
super();
System.out.println("这是son的带参构造方法");
}
}
package miangxiangduixiang03;
public class fathertest {
public static void main(String[] args) {
son1 s = new son1();
System.out.println("-----------------");
son1 s2 = new son1("林");
}
}
结果为:
这是father的无参构造方法
这是son的无参构造方法
-----------------
这是father的无参构造方法
这是son的带参构造方法
继承中构造方法的注意事项
如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错
如何解决呢???
A 在父类中加一个无参构造方法
B 通过使用super关键字去显示的调用父类的其他构造方法
C 子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问父类的构造方法,否则父类数据就没有初始化
注:this(.......)或者super(......)必须出现在第一条语句上,如果不是放在第一条语句上,
就可能对父亲的数据进行了多次初始化,所以必须放在第一条语句上
package miangxiangduixiang03;
public class father {
int age;
/*public father(){
System.out.println("这是father的无参构造方法");
}*/
public father(String name){
System.out.println("这是father的带参构造方法");
}
}
package miangxiangduixiang03;
public class son1 extends father {
public son1(){
super("");
System.out.println("这是son的无参构造方法");
/*super("");error,必须放在第一条语句*/
}
public son1(String name){
this();
System.out.println("这是son的带参构造方法");
}
}
package miangxiangduixiang03;
public class fathertest {
public static void main(String[] args) {
son1 s = new son1();
System.out.println("-----------------");
son1 s2 = new son1("林");
}
}
结果为:
这是father的带参构造方法
这是son的无参构造方法
-----------------
这是father的带参构造方法
这是son的无参构造方法
这是son的带参构造方法
继承中成员方法关系
案例演示
- 子父类中同名和不同名的成员方法
结论
- 通过子类对象去访问一个方法
1、首先在子类找
2、 然后在父类找
3、 如果还是没有找到就报错(不考虑父亲的父亲.......)
继承中成员方法关系
A 子类中的方法和父类中的方法声明不一样
B 子类中的方法和父类中的方法声明一样
通过子类调用方法:
a 先找子类中,看看有没有这个方法,有就使用
b 再找父类中,看看有没有这个方法,有就使用
c 如果没有就报错
package miangxiangduixiang03;
public class father2 {
public void show(){
System.out.println("father show");
}
}
package miangxiangduixiang03;
public class son2 extends father2{
public void method(){
System.out.println("method fangfa");
}
public void show(){
System.out.println("son show");
}
}
package miangxiangduixiang03;
public class father2test {
public static void main(String[] args) {
son2 s = new son2();
s.show();
s.method();
/*s.function();error 找不到符号*/
}
}
结果为:
son show
method fangfa
方法重写的应用
方法重写概述
- 子类中出现和父类中一模一样的方法声明,也被称为方法覆盖,方法复写
- 使用特点:
如果方法名不同,就调用对应的方法
如果方法名相同,最终使用的是子类自己的
方法重写的应用
- 当子类需要父类的功能,而功能主体子类有自己特有的内容时,可以重写父类中的方法,这样既沿袭了父类的功能,又定义了子类特有的内容
方法重写:
- 子类中出现和父类中方法声明一样的方法
(不同的类中,方法名一样,参数列表一样,返回值一样)
方法重载
- 本类中出现的方法名一样,参数列表不同的方法,与返回值无关
案例
package miangxiangduixiang03;
/*定义一个手机类
通过研究,又发现了一个新手机,可以在打完电话后听天气预报
按照我们基本的设计,我们把代码写了出来
但是呢?我们又发现新手机是手机,所以他应该继承手机类
但是这个设计不是最好的,因为打电话这个功能本来就是手机本身所具备的,所以新手机不提供这个功能,
但是,当我们将new手机类的打电话方法去掉后,他不能打电话了,所以这个不好
最终还是要加上这个功能,由于他继承了手机类,所以我们直接使用父类的功能就行了
那么,怎么使用父类的功能呢?前面讲过的super关键字*/
public class phone {
public void call(String name){
System.out.println("给"+name+"打电话");
}
}
package miangxiangduixiang03;
public class newphone extends phone {
public void call(String name){
//System.out.println("给"+name+"打电话");
super.call(name);
System.out.println("打完电话我还可以听天气预报");
}
}
package miangxiangduixiang03;
public class phonetest {
public static void main(String[] args) {
newphone np = new newphone();
np.call("小菜");
}
}
结果为:
给小菜打电话
打完电话我还可以听天气预报
方法重写的注意事项
- 父类中私有方法不能被重写
(因为父类方法子类就根本无法继承,所以就压根谈不上重写) - 子类重写父类方法是,访问权限不能更低
(子类重写的父类方法>=父类的访问权限,不能更低,最好一致) - 如果父类是静态方法,子类也必须通过静态方法来重写
package miangxiangduixiang03;
public class father3 {
/*private void show(){
System.out.println("这是私有方法");
}*/
public void show(){
System.out.println("这是public方法");
}
}
package miangxiangduixiang03;
public class son3 extends father3 {
/*public void method(){
System.out.println("这是共同方法");
}*/
/*void method(){
super();error,因为子类访问权限没有父类大
}*/
public void method2(){
System.out.println("这也是public方法");
}
}
package miangxiangduixiang03;
public class father3test {
/*son3 s = new son3();
s.method();
s.show();error,不能访问父类私有成员方法
*/
public static void main(String[] args) {
son3 s= new son3();
s.method2();
s.show();
}
}
结果为:
这也是public方法
这是public方法