- 🚀 一、继承
- 🌟 1.1 为什么需要继承?
- 🌟 1.2 继承的概念
- 🌟 1.3 继承的语法
- 🚀 二、 父类成员访问
- 🌟 2.1 子类访问父类成员变量
- 🌟 2.2 子类访问父类成员方法
- 🌟 2.3 super 关键字
- 🌟 2.4 子类构造方法
- 🌟 2.5 super 和 this
- 🌟 2.6 回顾代码块
- 🚀 三、final 关键字
- 🚀 四、继承和组合
Java 中使用类对现实世界中实体来进行描述,类经过实例化之后产生对象,可以用来表示现实中的实体,但是事物之间可能存在关联,那就要考虑继承。
看下面这两个类:
class Dog{
String name;
int age;
float weight;
public void eat(){
System.out.println("狗吃骨头");
}
}
class Cat{
String name;
int age;
float weight;
public void eat(){
System.out.println("猫吃鱼");
}
}
可以看到上面的代码中的两个类中存在着大量的重复。
那么如何将这些相同的代码抽取呢?
面向对象思想中提出了继承的概念,专门来进行共性抽取,实现代码复用。
继承机制:是面向对象程序设计中使代码可以复用的最重要的手段,它允许在保持原有类特性的基础上进行扩展,增加新功能,这样产生的类称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。
主要解决的问题:共性的抽取,实现代码复用。
下面用继承重写上面的代码:
class Animal{
String name;
int gae;
float weight;
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
上面的代码中,Dog 和 Cat 都继承 Animal 类,其中 Animal 类称为基类或父类,Dog 和 Cat 都是子类。
🌟 1.3 继承的语法子类可以使用父类中的成员,子类在实现时只需关心自己新添加的成员。
JAVA 中表示类之间的继承关系,要使用到 extends 关键字
修饰符 class 子类名 extends 父类名{
// ....
}
❗ 注意:
🚀 二、 父类成员访问 🌟 2.1 子类访问父类成员变量
- 子类会将父类的成员变量或者成员方法继承。
- 子类继承父类之后,必须新添加自己特有的成员,体现与父类的不同,否则就没必要继承了。
- JAVA 中一个子类只能继承一个父类。
- 父类的 private 属性成员,子类无法访问。
- 子类实例中包含父类的实例,使用 super 关键字访问父类实例。
- 如果访问的成员子类中有,优先访问自己的成员变量。
- 如果访问的成员子类中无,访问从父类继承下来的,如果父类无定义,则报错。
- 如果访问的成员变量与父类中的成员变量同名,则优先访问自己的。
成员变量的访问遵循优先原则,自己有就优先访问,没有就父类中找。
- 通过子类对象访问父类与子类不同名方法时,优先在子类中找,找到则访问。否则在父类中找,找到就访问,否则报错。
- 通过子类对象访问父类与子类不同名方法时,如果父类与子类的同名方法构成重载,根据调用方法传递的参数选择合适的访问,没有则报错。
如果子类存在与父类相同的成员,如何在子类对象中访问父类相同名称的成员呢?
🌟 2.3 super 关键字super 关键字作用:在子类方法中访问父类的成员。
class Base{
int a;
int b;
public void methodA(){
System.out.println("Base的方法1");
}
public void methodB(){
System.out.println("Base的方法2");
}
}
class child extends Base{
int a; // 与父类变量名相同且类型相同
char b; // 与父类变量名相同但类型不同
// 与父类中的 methodA 构成重载
public void methodA(int a) {
System.out.println("child的方法1");
}
@Override
// 重写父类 methodB
public void methodB(){
System.out.println("child的方法2");
}
public void methodC(){
// 对于同名的成员变量,直接访问,访问的都是子类的
a = 100;
b = 101;
// 访问父类的成员变量时,借助 super 关键字
super.a = 200;
super.b = 201;
// 父类和子类重载的方法,可以直接通过参数列表区分访问父类还是子类
methodA(); // 无参,访问父类 methodA
methodA(20); // 传递 int 参数,访问子类 methodA。
// 在子类访问重写的父类方法,借助 super 关键字
methodB(); // 访问子类
super.methodB(); // 访问父类
}
}
子类方法中,要明确访问父类中成员,借助 super 关键字即可。
❗ 【注意事项】:
🌟 2.4 子类构造方法
- super 只能在非静态方法中使用。
- 在子类方法中,访问父类的成员变量和方法。
子类对象构造时,要先调用父类的构造方法,再执行子类构造方法。
public class Base {
// 父类构造方法
public Base(){
System.out.println("父类构造了");
}
}
class Child extends Base{
// 子类构造方法
public Child() {
// super(); // 子类构造方法中会默认调用父类的无参构造方法。
// 用户没有写时,编译器会自动添加,super() 必须是构造方法中第一条语句。
// 并且只能出现一次
System.out.println("子类构造了");
}
}
/* 输出:
* 父类构造了
* 子类构造了
/
// super(a,b); 调用父类两个参数的构造方法
子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分,在构造子类对象时,要先调用父类的构造方法,将从父类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己的成员初始化完整。
🌟 2.5 super 和 thissuper 和 this 都可以在成员方法中来访问其他成员,他们之间有什么区别呢?
⛅相同点:
- 都是Java中的关键字。
- 只能在类的非静态方法中使用,访问非静态成员变量和方法。
- 在构造方法中调用时,必须是构造方法中第一条语句。
⛅不同点:
- this 是当前对象的引用,是调用实例方法的对象。super 是子类对象从父类继承下来部分成员的引用。
- 非静态方法中, this 用来访问本类的方法和属性。super 访问父类继承下来的方法和属性。
- 构造方法中,this(…) 调用本类的构造方法,super(…) 调用父类的构造方法,两种调用方法不能同时存在。
class A{
static{
System.out.println("A的静态代码块被执行了");
}
{
System.out.println("A的实例代码块被执行了");
}
public A(){
System.out.println("A的构造方法被执行了");
}
}
class B extends A{
static{
System.out.println("B的静态代码块被执行了");
}
{
System.out.println("B的实例代码块被执行了");
}
public B(){
System.out.println("B的构造方法被执行了");
}
}
public class t3 {
public static void main(String[] args) {
B b = new B();
}
}
/* 输出:
A的静态代码块被执行了
B的静态代码块被执行了
A的实例代码块被执行了
A的构造方法被执行了
B的实例代码块被执行了
B的构造方法被执行了
/
⛅继承关系上的代码块执行顺序:
🚀 三、final 关键字
- 父类静态代码块先于子类静态代码块执行,且最早执行。
- 父类实例代码块和父类构造方法紧接着执行。
- 子类实例代码块和子类构造方法紧接着再执行。
- 第二次实例化子类对象时,静态代码块都不会执行。
final 关键字修饰变量,成员方法以及类
- 修饰变量,表示为一个常量(即不能被修改)
final int a = 10;
a = 20; // 编译出错
- 修饰类:表示该类不能被继承
final class Animal{
...
}
class Bird extends Animal{
...
}
// 编译出错,无法从 Animal 继承。
String 类就是 final 修饰的,不能被继承
3. 修饰方法:表示该方法不能被重写。
和继承类似,组合也是一种表达类之间关系的方式。同样可以实现代码复用,但是没有用到 extends 关键字,将一个类的实例作为另一个类的成员。
class Tire{
...
}
class Engine{
...
}
class VehicleSystem{
...
}
class Car{
private Tire tire; // 可以复用 Tire 类的属性和方法
private Engine engine; // 可以复用 Engine 类的属性和方法
private VehicleSyetem vs; // 可以复用 Vs 类的属性和方法
}
继承和组合都可以实现代码的复用,一般来说:能用组合尽量用组合。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)