本篇文章将给大家介绍面向对象的三大特点之一的继承性
继承的概念
-
如何描述继承
在Java中类的继承是指在一个现有类的基础上去构建一个新的类,在这基础上的新的类是子类,原来的类是父类。子类会继承父类的属性和方法,使子类对象具有父类的特征和行为。 -
为什么会需要继承
Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是
现实世界错综复杂,事物之间可能会存在一些关联,如猫和狗它们都是动物也都会吃饭,在创建类时都会有名字和年龄。
就像如下代码:
public class Cat {
String name;
int age;
public void eat(){
System.out.println("吃东西");
}
public void mimi(){
System.out.println("喵喵...");
}
}
public class Dog {
String name;
int age;
public void eat(){
System.out.println("吃东西");
}
public void waWa(){
System.out.println("汪汪...");
}
}
在以上代码中分别创建了两个类,可以发现这两个类中除了有一个方法不同外,其他部分都相同,造成了代码的重复。
那能否将这些共性抽取呢?面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用。
- 继承的概念
继承:是面向对象程序设计使代码可以复用的最重要的手段,它可以在保持原有类特性的基础上进行扩展,增加新功能
继承主要解决的问题是:共性的抽取,实现代码复用。
例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。
以此来增强开发的效率。 - 继承的语法
在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:
修饰符 class 子类 extends 父类 {
// ...
}
继承的语法
- extends关键字
在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:
修饰符 class 子类 extends 父类 {
// ...
}
用继承将上述代码重写 代码如下
public class Animal {
String name;
int age;
public void eat(){
System.out.println("吃东西");
}
}
public class Cat extends Animal{
public void mimi(){
System.out.println("喵喵...");
}
}
public class Dog extends Animal{
public void waWa(){
System.out.println("汪汪...");
}
}
注意:
1.子类会将父类中的成员变量或者成员方法继承到子类中
2.子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了
2. 父类成员访问
子类既然继承了父类的方法和字段就可以访问父类的成员
2.1 在子类中访问父类的成员变量
1.子类和父类不存在同名成员变量
代码如下
public class Base {
int a;
int b;
}
public class Derived extends Base{
int c;
public void method(){
a = 10; // 访问从父类中继承下来的a
b = 20; // 访问从父类中继承下来的b
c = 30; // 访问子类自己的c
}
}
2 子类和父类成员变量同名
public class Base {
int a;
int b;
int c;
}
public class Derived extends Base{
int a; // 与父类中成员a同名,且类型相同
char b; // 与父类中成员b同名,但类型不同
public void method(){
a = 100;
b = 101;
c = 102;
}
}
通过简单的测试可以发现a访问的是子类的,b访问的也是子类的,c访问的是父类的
在子类方法中 或者 通过子类对象访问成员时:
如果访问的成员变量子类中有,优先访问自己的成员变量。
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。
那么如果子类中存在与父类中相同的成员,如何在子类中访问父类相同名称的成员呢?
2.2 super关键字
该关键字主要作用是:在子类方法中访问父类的成员。
调用代码如下
class pass{
int a=100;
int b=101;
}
class passWord extends pass{
int a=45;
int b=10;
public void test(){
System.out.println(a);
System.out.println(b);
System.out.println(super.a);
System.out.println(super.b);
}
}
public class test {
public static void main(String[] args) {
passWord passWord = new passWord();
passWord.test();
}
}
通过super’关键字就可以访问父类的成员
需要注意的是
1.只能在非静态方法中使用
2.在子类方法中,访问父类的成员变量和方法。
【区别】提到super关键字就不得不提到this关键字了
这两个关键字都是在类中使用的那么这两个关键字有什么区别呢?
1.this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成
员的引用
2.在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
3.在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造
方法中出现
4.构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有
2.3子类构造方法
在子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。
public class Animal {
String name;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
int age;
public void eat(){
System.out.println("吃东西");
}
}
public class Dog extends Animal{
String color;
public void waWa(){
System.out.println("汪汪...");
}
public Dog(String name, int age,String color) {
super(name, age);
this.color=color;
}
}
如代码所示:在子类继承了父类后首先使用super关键字对父类成员进行初始化
1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的
父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(…)只能在子类构造方法中出现一次,并且不能和this同时出现
继承方式
在现实生活中继承是什么复杂和灵活的。
在Java中只支持以下几种继承方式
多继承在Java中是不被支持的,一个类只能继承一个类而不能继承多个类
继承与组合
和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法, 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物
组合表示对象之间是has-a的关系,比如:汽车
// 轮胎类
class Tire{
}
//发动机类
class Engine{
// ...
} /
/ 车载系统类
class VehicleSystem{
// ...
}
class Car{
private Tire tire; // 可以复用轮胎中的属性和方法
private Engine engine; // 可以复用发动机中的属性和方法
private VehicleSystem vs; // 可以复用车载系统中的属性和方法
// ...
} /
// 奔驰是汽车
class Benz extend Car{
// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}
组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择。
本篇对继承的介绍就到此结束了,如果对您有帮助的话可以三连哦~~~~