【java】详解继承


本篇文章将给大家介绍面向对象的三大特点之一的继承性


继承的概念

  1. 如何描述继承
    在Java中类的继承是指在一个现有类的基础上去构建一个新的类,在这基础上的新的类是子类,原来的类是父类。子类会继承父类的属性和方法,使子类对象具有父类的特征和行为。

  2. 为什么会需要继承
    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("汪汪...");
    }
}

在以上代码中分别创建了两个类,可以发现这两个类中除了有一个方法不同外,其他部分都相同,造成了代码的重复。
那能否将这些共性抽取呢?面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用。

  1. 继承的概念
    继承:是面向对象程序设计使代码可以复用的最重要的手段,它可以在保持原有类特性的基础上进行扩展,增加新功能
    继承主要解决的问题是:共性的抽取,实现代码复用。
    例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。
    以此来增强开发的效率。
  2. 继承的语法
    在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:
修饰符 class 子类 extends 父类 {
// ...
}

继承的语法

  1. 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{
// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}

组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择。


本篇对继承的介绍就到此结束了,如果对您有帮助的话可以三连哦~~~~

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值