day15_面向对象的三大特征之一(继承)
创始人
2024-03-08 23:16:04

继承的概述

Java是对现实社会的模拟,现实中有儿子可以继承父亲的财产,因此有了富二代的。 java中多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成某种关系。如图所示:

其中,多个类可以称为子类,也叫派生类;多个类抽取出来的这个类称为父类超类(superclass)或者基类继承描述的是事物之间的所属关系,这种关系是:is-a 的关系。例如,图中猫属于动物,狗也属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。

继承的好处

  • 提高代码的复用性
  • 提高代码的扩展性
  • 类与类之间产生了关系,是多态的前提

继承的格式

通过 extends关键字,可以声明一个子类继承另外一个父类,定义格式如下:

继承演示,代码如下:  

现实中通用的属性和功能定义在父类中

/** 定义人类Person,做为父类*/
public class Person {//成员变量 对应 现实中的属性private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}// 成员方法 对应现实中的功能public void showInfo(){System.out.println("姓名:" +name +"年龄:" + age);}
}

定义Student子类

/** 定义Student类继承 人类Person*/
public class Student extends Person {//独有的方法public void study() {System.out.println("学习..");}
}

定义Teacher子类

/** 定义Teacher类继承 人类Person*/
public class Teacher extends Person{//独有的方法public void teaching() {System.out.println("教书..");}
}

定义测试类

public class Test {public static void main(String[] args) {//创建子类Student对象Student student = new Student();//调用从父类继承的方法 和变量student.setName("张三");student.setAge(18);student.showInfo(); //姓名:张三  年龄:18//调用本类独有的方法student.study(); //学习..//创建子类Teacher对象Teacher teacher = new Teacher();//调用从父类继承的方法 和变量teacher.setName("李四");teacher.setAge(28);teacher.showInfo(); //姓名:李四  年龄:28//调用本类独有的方法teacher.teaching(); //教书..}
}

继承的特点

  • Java只支持单继承,不支持多继承
//一个类只能有一个父类,不可以有多个父类。
class C extends A{} 	//ok
class C extends A,B...	//error
  •  Java支持多层继承(继承体系)。顶层父类是Object类。所有的类默认继承Object,作为父类。
class A{}
class B extends A{}
class C extends B{}
  • 子类和父类是一种相对的概念。例如:B类对于A来说是子类,但是对于C类来说是父类
  •  一个父类可以同时拥有多个子类

继承的中成员变量的访问

  • 父类中的成员,无论是公有(public)还是私有(private),均会被子类继承。
  • 子类虽会继承父类私有(private)的成员,但子类不能对继承的私有成员直接进行访问,可通过继承的get/set方法进行访问。如图所示:

代码示例

/** 定义动物类Animal,做为父类*/
class Animal {// 定义name属性private String name;// 定义age属性public int age;// 定义动物的吃东西方法public void eat() {System.out.println(age + "岁的" + name + "在吃东西");}
}/** 定义猫类Cat 继承 动物类Animal*/
class Cat extends Animal {// 定义一个猫抓老鼠的方法catchMousepublic void catchMouse() {System.out.println("抓老鼠");}
}/** 定义测试类*/
public class Test {public static void main(String[] args) {// 创建一个猫类对象Cat cat = new Cat();// 为该猫类对象的name属性进行赋值//cat.name = "Tom";// 编译报错,不能直接访问父类中私有的成员// 为该猫类对象的age属性进行赋值cat.age = 2;// 调用该猫的catchMouse()方法cat.catchMouse(); //抓老鼠// 调用该猫继承来的eat()方法cat.eat(); //2岁的null在吃东西}
}

如果子父类中有重名的成员变量,子类中如何访问父类中的成员变量

  • 当父类的成员变量私有化时,在子类中是无法直接访问的,如果想要访问父类的私有成员变量,只能通过父类的get/set方法访问。所以是否重名不影响
  • 当父类的成员变量非私有时,在子类中可以直接访问,所以如果有重名时,就需要加“super."进行区别。

代码示例

class Animal {private String name = "动物";public int age = 118;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}class Cat extends Animal {// private String name = "猫";public int age = 18;public void show() {// System.out.println("种类:"+ super.name);  编译报错,父类私有的成员变量子类不能直接访问//通过GetXxx方法访问System.out.println("种类:" + getName()); //种类:动物//直接访问变量名称使用的是本类中的System.out.println("我的年龄:" + age); //我的年龄:18// 使用super来访问父类中的非私有成员System.out.println("我父亲的年龄是:" + super.age); //我父亲的年龄是:118}
}public class Test {public static void main(String[] args) {Cat cat = new Cat();cat.show();}
}

继承的中成员方法的访问

我们说父类的所有方法子类都会继承,我们不能直接访问父类中私有的成员方法,但是可以间接访问。

class Animal {private void introduce() {System.out.println("我是动物老大");}public void info(){introduce();}}class Cat extends Animal {}public class Test {public static void main(String[] args) {Cat cat = new Cat();// cat.introduce(); 子类不能直接访问父类中私有的成员方法//间接访问cat.info(); //我是动物老大}
}

我们也可以直接调用父类中,非私有的成员方法

class Animal {public void eat() {System.out.println("我是动物,要吃东西");}}class Cat extends Animal {}public class Test {public static void main(String[] args) {Cat cat = new Cat();cat.eat(); //我是动物,要吃东西}
}

方法重写

当子类中出现了与父类一模一样的方法时,我们称之为方法重写 (Override) 。应用场景:子类觉得父类原来的实现方法不适合于子类。比如新的手机增加来电显示头像的功能,代码如下

class Phone {public void sendMessage() {System.out.println("发短信");}public void call() {System.out.println("打电话");}public void showNum() {System.out.println("来电显示号码");}
}//智能手机类
class NewPhone extends Phone {//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能public void showNum() {//调用父类已经存在的功能使用supersuper.showNum();//增加自己特有显示姓名和图片功能System.out.println("显示来电姓名");System.out.println("显示头像");}
}public class Test {public static void main(String[] args) {// 创建子类对象NewPhone np = new NewPhone();// 调用父类继承而来的方法np.call();np.sendMessage();// 调用子类重写的方法np.showNum();}
}

注意事项:

@Override:写在方法上面,用来检测是不是有效的正确覆盖重写。这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。建议保留

必须保证父子类之间方法的名称相同,参数列表也相同。大部分情况下,我们只要保证要重写的方法一模一样就好,除非有特殊要求。任何情况下也不能违背下面几点原则

返回值类型:

  • 引用类型:子类方法的返回值类型必须【小于等于】父类方法的返回值类型(小于其实就是是它的子类,例如:Student < Person)。
  • 基本类型:如果返回值类型是基本数据类型和void,那么必须是相同

子类方法的访问权限必须【大于等于】父类方法的访问权限修饰符。 小扩展提示:public > protected > 缺省 > private

几种特殊的方法不能被重写

  • 静态方法不能被重写
  • 私有等在子类中不可见的方法不能被重写
  • final方法不能被重写

继承的中构造方法的访问

当类之间产生了关系,其中各类中的构造方法,又产生了哪些影响呢?

首先我们要回忆两个事情,构造方法的定义格式和作用。

  1. 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。

  2. 构造方法的作用是初始化实例变量的,而子类又会从父类继承所有成员变量。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super() ,表示调用父类的实例初始化方法,父类成员变量初始化后,才可以给子类使用。

代码示例

class Fu{public Fu() {System.out.println("我是父类中的无参数构造器");}
}
class Zi extends Fu{public Zi() {System.out.println("我是Zi类中的无参数构造器");}
}public class Test {public static void main(String[] args) {Zi zi = new Zi();/*输出结果:我是父类中的无参数构造器我是Zi类中的无参数构造器*/}}

如果父类没有无参构造怎么办?

class Fu{public int number;public Fu(int number) {System.out.println("我是父类中的有参数构造器");}
}
class Zi extends Fu{public Zi() { //此时子类代码报错。System.out.println("我是Zi类中的无参数构造器");}
}

解决办法:在子类构造器中,用super(实参列表),显示调用父类的有参构造解决。

class Fu {public int number;public Fu(int number) {System.out.println("我是父类中的有参数构造器: " + number);}
}class Zi extends Fu {public Zi() {super(1); //用super(实参列表),显示调用父类的有参构造解决System.out.println("我是Zi类中的无参数构造器");}
}public class Test {public static void main(String[] args) {Zi zi = new Zi();/*输出结果:我是父类中的有参数构造器: 1我是Zi类中的无参数构造器*/}}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...