JAVA基础学习-接口与继承

73 篇文章 0 订阅
73 篇文章 0 订阅

8.1 接口

在设计LOL的时候,进攻类英雄有两种,一种是进行物理系攻击,一种是进行魔法系攻击

这时候,就可以使用接口来实现这个效果。

接口就像是一种约定,我们约定某些英雄是物理系英雄,那么他们就一定能够进行物理攻击。

  • ​物理攻击接口

创建一个接口 AD ,声明一个方法 physicAttack 物理攻击,但是没有方法体,是一个“”方法

package charactor;
 
public interface AD {
        //物理伤害
    public void physicAttack();
}
  • 设计一类英雄,能够使用物理攻击

设计一类英雄,能够使用物理攻击,这类英雄在LOL中被叫做AD类:ADHero 继承了Hero 类,所以继承了name,hp,armor等属性

实现某个接口,就相当于承诺了某种约定

所以,实现AD这个接口,就必须提供AD接口中声明的方法physicAttack() 实现在语法上使用关键字 implements

package charactor;
 
public class ADHero extends Hero implements AD{
 
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
 
}
  • 魔法攻击接口

package charactor;
 
public class APHero extends Hero implements AP{
 
    @Override
    public void magicAttack() {
        System.out.println("进行魔法攻击");
    }
 
}
  • 设计一类英雄,既能进行物理攻击,又能进行魔法攻击

一种英雄,能够同时进行物理攻击和魔法攻击 比如伊泽瑞尔,皮城女警凯特琳

package charactor;
  
//同时能进行物理和魔法伤害的英雄
public class ADAPHero extends Hero implements AD,AP{
  
    @Override
    public void magicAttack() {
        System.out.println("进行魔法攻击");
    }
  
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
  
}

  • 什么样的情况下该使用接口?

如上的例子,似乎要接口,不要接口,都一样的,那么接口的意义是什么呢

学习一个知识点,是由浅入深得进行的。 这里呢,只是引入了接口的概念,要真正理解接口的好处,需要更多的实践,以及在较为复杂的系统中进行大量运用之后,才能够真正理解,比如在学习了多态之后就能进一步加深理解。

刚刚接触一个概念,就希望达到炉火纯青的学习效果,这样的学习目标是不科学的。

8.2 对象转型

  • 明确引用类型与对象类型的概念

首先,明确引用类型与对象类型的概念 在这个例子里,有一个对象 new ADHero(), 同时也有一个引用ad 对象是有类型的, 是ADHero 引用也是有类型的,是ADHero 通常情况下,引用类型和对象类型是一样的 接下来要讨论的类型转换的问题,指的是引用类型和对象类型不一致的情况下的转换问题

package charactor;

public class Hero {
	public String name; 
	protected float hp;
	public static void main(String[] args) {
		ADHero ad = new ADHero();
	}
}

  • 子类转父类(向上转型)

所谓的转型,是指当引用类型对象类型不一致的时候,才需要进行类型转换

父类指向子类对象是一定可以成功的。

package charactor;

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0cd3df775bab463f83dacdbb53e8c5ec~tplv-k3u1fbpfcp-watermark.image?)
public class Hero {
	public String name; 
	protected float hp;
	public static void main(String[] args) {
		Hero h = new Hero();
		ADHero ad = new ADHero();
		//类型转换指的是把一个引用所指向的对象的类型,转换为另一个引用的类型
		//把ad引用所指向的对象的类型是ADHero
		//h引用的类型是Hero
		//把ADHero当做Hero使用,一定可以 
		h = ad;
	}
}

  • 父类转子类(向下转型)

父类转子类,有的时候行,有的时候不行,所以必须进行强制转换。 强制转换的意思就是 转换有风险,风险自担。

 

package charactor;
import charactor1.Support;
 
public class Hero {
    public String name; 
    protected float hp;
    public static void main(String[] args) {
        Hero h =new Hero();
        ADHero ad = new ADHero();
        Support s =new Support();
         
        h = ad;
        ad = (ADHero) h; //可以成功
        h = s;
        ad = (ADHero)h;  //指向失败
    }
}
  • 没有继承关系的两个类,互相转换

没有继承关系的两个类,互相转换,一定会失败。 虽然ADHero和APHero都继承了Hero,但是彼此没有互相继承关系。

 

package charactor;
public class Hero {
	public String name;
	protected float hp;

	public static void main(String[] args) {
		ADHero ad = new ADHero();
		APHero ap = new APHero();

		// 没有继承关系的类型进行互相转换一定会失败,所以会出现编译错误
		ad = (ADHero) ap;
	}
}
  • 实现类转换成接口(向上转型)

ad指向的对象是ADHero类型,这个类型实现了AD接口。 实现AD接口的类ADHero一定可以转换为接口;

换句话说,接口可以指向实现此接口的类

package charactor;
public class Hero {
    public String name; 
    protected float hp;
      
    public static void main(String[] args) {
        ADHero ad = new ADHero();
        AD adi = ad;
    } 
}

 

  • 接口转换成实现类(向下转型)

实现类指向接口不一定可以成功,需要强制转换。

 

10行: ad引用指向ADHero, 而adi引用是接口类型:AD,实现类转换为接口,是向上转型,所以无需强制转换,并且一定能成功 12行: adi实际上是指向一个ADHero的,所以能够转换成功 14行: adi引用所指向的对象是一个ADHero,要转换为ADAPHero就会失败。

假设能够转换成功,那么就可以使用magicAttack方法,而adi引用所指向的对象ADHero没有magicAttack方法的。

package charactor;
public class Hero {
    public String name; 
    protected float hp;
        
    public static void main(String[] args) {
        ADHero ad = new ADHero();
        AD adi = ad;
        
        ADHero adHero = (ADHero) adi;
        ADAPHero adapHero = (ADAPHero) adi;
        adapHero.magicAttack();
    } 
}

  • instanceof Hero 判断一个引用所指向的对象,是否是Hero类型,或者Hero的子类

8.3 重写

子类可以继承父类的对象方法;在继承后,重复提供该方法,就叫做方法的重写。

又叫覆盖 override

  • 父类Item有一个方法,叫做effect

package property;
 
public class Item {
    String name;
    int price;
 
    public void buy(){
        System.out.println("购买");
    }
    public void effect() {
        System.out.println("物品使用后,可以有效果");
    }
 
}
  • 子类LifePotion继承Item,同时也提供了方法effect

package property;
 
public class LifePotion extends Item{
     
    public void effect(){
        System.out.println("血瓶使用后,可以回血");
    }
     
}
  • 调用重写的方法

调用就会执行重写的方法,而不是从父类的方法。 所以LifePotion的effect会打印: "血瓶使用后,可以回血"

package property;
public class Item {
    String name;
    int price;
     
    public void effect(){
        System.out.println("物品使用后,可以有效果");
    }
     
    public static void main(String[] args) {
        Item i = new Item();
        i.effect();
         
        LifePotion lp =new LifePotion();
        lp.effect();
    }
}

  • 如果没有重写这样的机制怎么样?

如果没有重写这样的机制,也就是说LifePotion这个类,一旦继承了Item,所有方法都不能修改了。

但是LifePotion又希望提供一点不同的功能,为了达到这个目的,只能放弃继承Item,重新编写所有的属性和方法,然后在编写effect的时候,做一点小改动.

这样就增加了开发时间和维护成本

package property;
 
public class LifePotion {
    String name;
    int price;
 
    public void buy(){
        System.out.println("购买");
    }
    //只能放弃继承Item
    public void effect(){
        System.out.println("血瓶使用后,可以回血");
    }

8.4 多态

  • 操作符的多态

同一个操作符在不同情境下,具备不同的作用 如果+号两侧都是整型,那么**+代表 数字相加** 如果+号两侧,任意一个是字符串,那么**+代表字符串**

package charactor;
public class Hero {
    public String name;
    protected float hp;
    public static void main(String[] args) {
         
        int i = 5;
        int j = 6;
        int k = i+j; //如果+号两侧都是整型,那么+代表 数字相加
         
        System.out.println(k);
         
        int a = 5;
        String b = "5";
         
        String c = a+b; //如果+号两侧,任意一个是字符串,那么+代表字符串连接
        System.out.println(c);    
    }  
}
  • 观察类的多态现象

观察类的多态现象:

  1. i1和i2都是Item类型

  2. 都调用effect方法

  3. 输出不同的结果

多态: 都是同一个类型,调用同一个方法,却能呈现不同的状态

Item.java:

package property;
 
public class Item {
    String name;
    int price;
 
    public void buy(){
        System.out.println("购买");
    }
    public void effect() {
        System.out.println("物品使用后,可以有效果 ");
    }
     
    public static void main(String[] args) {
        //父类引用指向子类实例
        Item i1= new LifePotion();
        Item i2 = new MagicPotion();
        System.out.print("i1  是Item类型,执行effect打印:");
        i1.effect();
        System.out.print("i2也是Item类型,执行effect打印:");
        i2.effect();
    }
 
}

LifePotion.java

package property;
 
public class LifePotion extends Item {
    public void effect(){
        System.out.println("血瓶使用后,可以回血");
    }
}

MagicPotion.java

package property;
 
public class MagicPotion extends Item{
    public void effect(){
        System.out.println("蓝瓶使用后,可以回魔法");
    }
}
  • 类的多态条件

要实现类的多态,需要如下条件

  1. 父类(接口)引用指向子类对象

  2. 调用的方法有重写

那么多态有什么作用呢? 通过比较不使用多态与使用多态来进一步了解

package charactor;
 
import property.LifePotion;
import property.MagicPotion;
   
public class Hero {
    public String name;
    protected float hp;
 //java学习交流:737251827  进入可领取学习资源及对十年开发经验大佬提问,免费解答!
    public void useLifePotion(LifePotion lp){
        lp.effect();
    }
    public void useMagicPotion(MagicPotion mp){
        mp.effect();
    }
 
    public static void main(String[] args) {
         
        Hero garen =  new Hero();
        garen.name = "盖伦";
     
        LifePotion lp =new LifePotion();
        MagicPotion mp =new MagicPotion();
         
        garen.useLifePotion(lp);
        garen.useMagicPotion(mp);
    }
}

如果不使用多态,假设英雄要使用血瓶和魔瓶,就需要为Hero设计两个方法. useLifePotion useMagicPotion

除了血瓶和魔瓶还有很多种物品,那么就需要设计很多很多个方法,比如 usePurityPotion 净化药水 useGuard 守卫 useInvisiblePotion 使用隐形药水 等等等等

  • 类的多态-使用多态

如果物品的种类特别多,那么就需要设计很多的方法 比如useArmor,useWeapon等等

这个时候采用多态来解决这个问题 设计一个方法叫做useItem,其参数类型是Item 如果是使用血瓶,调用该方法 如果是使用魔瓶,还是调用该方法 无论英雄要使用什么样的物品,只需要一个方法即可

package charactor;
 
import property.Item;
import property.LifePotion;
import property.MagicPotion;
   
public class Hero {
    public String name;
    protected float hp;
 
    public void useItem(Item i){
        i.effect();
    }
 
    public static void main(String[] args) {
         
        Hero garen =  new Hero();
        garen.name = "盖伦";
     
        LifePotion lp =new LifePotion();
        MagicPotion mp =new MagicPotion();
         
        garen.useItem(lp);
        garen.useItem(mp);     
         
    } 
}

8.5 隐藏

与重写类似,方法的重写是子类覆盖父类的对象方法

隐藏,就是子类覆盖父类的类方法

  • 父类

父类有一个类方法 :battleWin

package charactor;
  
public class Hero {
    public String name;
    protected float hp;
  
    //类方法,静态方法
    //通过类就可以直接调用
    public static void battleWin(){
        System.out.println("hero battle win");
    }
      
}

  • 子类隐藏父类的类方法

package charactor;
  
public class ADHero extends Hero implements AD{
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
     
    //隐藏父类的battleWin方法
    public static void battleWin(){
        System.out.println("ad hero battle win");
    }   
     
    public static void main(String[] args) {
        Hero.battleWin();
        ADHero.battleWin();
    }
}

8.6 super关键字

  • 准备一个显式提供无参构造方法的父类

在实例化Hero对象的时候,其构造方法会打印“Hero的构造方法 "。

package charactor;
import property.Item;
 
public class Hero {
    String name; //姓名   
    float hp; //血量
    float armor; //护甲
    int moveSpeed; //移动速度
     
    public void useItem(Item i){
        System.out.println("hero use item");
        i.effect();
    }
     
    public Hero(){
        System.out.println("Hero的构造方法 ");
    }
     
    public static void main(String[] args) {
        new Hero();
    }   
}

  • 实例化子类,父类的构造方法一定会被调用

实例化一个ADHero(), 其构造方法会被调用:其父类的构造方法也会被调用,并且是父类构造方法先调用。子类构造方法会默认调用父类的 无参的构造方法。

package charactor;
public class ADHero extends Hero implements AD{
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
     
    public ADHero(){
        System.out.println("AD Hero的构造方法");
    }
     
    public static void main(String[] args) {
        new ADHero();  
    }
}

  • 父类显式提供两个构造方法

分别是无参的构造方法和带一个参数的构造方法

package charactor;
import property.Item;
 
public class Hero {
    String name; //姓名
    float hp; //血量
    float armor; //护甲
    int moveSpeed; //移动速度
     
    public void useItem(Item i){
        System.out.println("hero use item");
        i.effect();
    }   
     
    public Hero(){
        System.out.println("Hero的无参的构造方法 ");
    }
    public Hero(String name){
        System.out.println("Hero的有一个参数的构造方法 ");
        this.name = name;
    }
    public static void main(String[] args) {
        new Hero();
    }
}

  • 子类显式调用父类带参构造方法

package charactor;
  
public class ADHero extends Hero implements AD{
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
     
    public ADHero(String name){
        super(name);
        System.out.println("AD Hero的构造方法");
    }
     
    public static void main(String[] args) {
        new ADHero("德莱文");
    }
}

  • 调用父类属性

package charactor;
  
public class ADHero extends Hero implements AD{
    int moveSpeed=400; //移动速度
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
     
    public int getMoveSpeed(){
        return this.moveSpeed;
    }
    public int getMoveSpeed2(){
        return super.moveSpeed;
    }
     
    public static void main(String[] args) {
        ADHero h= new ADHero();
        System.out.println(h.getMoveSpeed());
        System.out.println(h.getMoveSpeed2());  
    }
}

  • 调用父类方法

ADHero重写了useItem方法,并且在useItem中通过super调用父类的useItem方法

package charactor;
 
import property.Item;
import property.LifePotion;
 
public class ADHero extends Hero implements AD {
    int moveSpeed = 400; // 移动速度
    @Override
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
 
    public int getMoveSpeed() {
        return this.moveSpeed;
    }
    public int getMoveSpeed2() {
        return super.moveSpeed;
    }
 
    // 重写useItem,并在其中调用父类的userItem方法
    public void useItem(Item i) {
        System.out.println("adhero use item");
        super.useItem(i);
    }
 
    public static void main(String[] args) {
        ADHero h = new ADHero();
        LifePotion lp = new LifePotion();
    }
}

8.7 Object类

Object类是所有类的父类

  • 声明一个类的时候,默认是继承了Object

  • toString()

Object类提供一个toString方法,所以所有的类都有toString方法。toString()的意思是返回当前对象的字符串表达。 通过 System.out.println 打印对象就是打印该对象的toString()返回值

package charactor;
  
public class Hero {
    public String name;
    protected float hp;
      
    public String toString(){
        return name;
    }
      
    public static void main(String[] args) {
        Hero h = new Hero();
        h.name = "盖伦";
        System.out.println(h.toString());
        //直接打印对象就是打印该对象的toString()返回值
        System.out.println(h);
    }
}
  • finalize()

当一个对象没有任何引用指向的时候,它就满足垃圾回收的条件

当它被垃圾回收的时候,它的finalize() 方法就会被调用。

finalize() 不是开发人员主动调用的方法,而是由虚拟机JVM调用的。

  • equals()

equals() 用于判断两个对象的内容是否相同

假设,当两个英雄的hp相同的时候,我们就认为这两个英雄相同

System.out.println(h1.equals(h2));
System.out.println(h1.equals(h3));
  • ==

这不是Object的方法,但是用于判断两个对象是否相同 更准确的讲,用于判断两个引用,是否指向了同一个对象

System.out.println(h1==h2);
System.out.println(h1==h3);

8.8 final

  • final修饰类

当Hero被修饰成final的时候,表示Hero不能够被继承;其子类会出现编译错误。

package charactor;
 
public final class Hero extends Object {  
    String name; //姓名
    float hp; //血量  
}
  • final修饰方法

Hero的useItem方法被修饰成final,那么该方法在ADHero中,不能够被重写

package charactor;
 
import property.Item;
 
public class Hero extends Object {
    public final void useItem(Item i){
        System.out.println("hero use item");
        i.effect();
    }   

    public static void main(String[] args) {
        new Hero();
    }
}
  • final修饰基本类型变量

final修饰基本类型变量,表示该变量只有一次赋值机会;

16行进行了赋值,17行就不可以再进行赋值了。

package charactor;
 
public class Hero extends Object {
    float hp; //血量

    public static void main(String[] args) {
        final int hp;
        hp = 5;
        hp = 6;
    }
}
  • final修饰引用

final修饰引用:h引用被修饰成final,表示该引用只有1次指向对象的机会。 所以17行会出现编译错误 但是,依然通过h引用修改对象的属性值hp,因为hp并没有final修饰

package charactor;
 
public class Hero extends Object {
    String name; //姓名
    float hp; //血量
    float armor; //护甲
    int moveSpeed; //移动速度
     
    public static void main(String[] args) {
        final Hero h;
        h  = new Hero();
        h  = new Hero();
         
        h.hp = 5;  
    }
}
  • 常量

常量指的是可以公开,直接访问,不会变化的值 比如 itemTotalNumber 物品栏的数量是6个

public static final int itemTotalNumber = 6;//物品栏的数量

8.9 抽象类

在类中声明一个方法,这个方法没有实现体,是一个“空”方法

这样的方法就叫抽象方法,使用修饰符“abstract"

当一个类有抽象方法的时候,该类必须被声明为抽象类

  • 抽象类

为Hero增加一个抽象方法 attack,并且把Hero声明为abstract的。 APHero,ADHero,ADAPHero是Hero的子类,继承了Hero的属性和方法。 但是各自的攻击手段是不一样的,所以继承Hero类后,这些子类就必须提供不一样的attack方法实现。

Hero.java

package charactor;
 
public abstract class Hero {
    String name;
    float hp;
    float armor;
    int moveSpeed;
 
    public static void main(String[] args) {}
 
    // 抽象方法attack
    // Hero的子类会被要求实现attack方法
    public abstract void attack();
}

ADHero.java

package charactor;
public class ADHero extends Hero implements AD {
    public void physicAttack() {
        System.out.println("进行物理攻击");
    }
 
    @Override
    public void attack() {
        physicAttack();
    }
}
  • 抽象类可以没有抽象方法

Hero类可以在不提供抽象方法的前提下,声明为抽象类 一旦一个类被声明为抽象类,就不能够被直接实例化

package charactor;
   
public abstract class Hero {
    String name;
    float hp;
    float armor;
    int moveSpeed;
       
    public static void main(String[] args) {
        //虽然没有抽象方法,但是一旦被声明为了抽象类,就不能够直接被实例化
        Hero h= new Hero();
    }
}
  • 抽象类和接口的区别

package charactor;
  
public interface AP {
  
    public static final int resistPhysic = 100;
     
    //resistMagic即便没有显式的声明为 public static final
    //但依然默认为public static final
    int resistMagic = 0;
     //java学习交流:737251827  进入可领取学习资源及对十年开发经验大佬提问,免费解答!
    public void magicAttack();
}

8.10 内部类

  • 非静态内部类

非静态内部类 BattleScore “战斗成绩”,非静态内部类可以直接在一个类里面定义。

比如:战斗成绩只有在一个英雄对象存在的时候才有意义;所以实例化BattleScore 的时候,必须建立在一个存在的英雄的基础上。 语法: new 外部类().new 内部类() 作为Hero的非静态内部类,是可以直接访问外部类的private实例属性name的

  • 静态内部类

在一个类里面声明一个静态内部类:比如敌方水晶,当敌方水晶没有血的时候,己方所有英雄都取得胜利,而不只是某一个具体的英雄取得胜利。

与非静态内部类不同,静态内部类水晶类的实例化 不需要一个外部类的实例为基础,可以直接实例化。语法:new 外部类.静态内部类();

因为没有一个外部类的实例,所以在静态内部类里面不可以访问外部类的实例属性和方法。除了可以访问外部类的私有静态成员外,静态内部类和普通类没什么大的区别

package charactor;
  
public class Hero {
    public String name;
    protected float hp;
    private static void battleWin(){
        System.out.println("battle win");
    }
     
    //敌方的水晶
    static class EnemyCrystal{
        int hp=5000;
        //如果水晶的血量为0,则宣布胜利
        public void checkIfVictory(){
            if(hp==0){
                Hero.battleWin(); 
                //静态内部类不能直接访问外部类的对象属性
                System.out.println(name + " win this game");
            }
        }
    }
    public static void main(String[] args) {
        //实例化静态内部类
        Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
        crystal.checkIfVictory();
    }
}
  • 匿名类

匿名类指的是在声明一个类的同时实例化它,使代码更加简洁精练。通常情况下,要使用一个接口或者抽象类,都必须创建一个子类。

有的时候,为了快速使用,直接实例化一个抽象类,并“当场”实现其抽象方法。 既然实现了抽象方法,那么就是一个新的类,只是这个类,没有命名。 这样的类,叫做匿名类

  • 本地类

本地类可以理解为有名字的匿名类。 内部类与匿名类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置。 本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方。

package charactor;
   
public abstract class Hero {
    String name; //姓名
          
    float hp; //血量
          
    float armor; //护甲
          
    int moveSpeed; //移动速度
      
    public abstract void attack();
      
    public static void main(String[] args) {
          
        //与匿名类的区别在于,本地类有了自定义的类名
        class SomeHero extends Hero{
            public void attack() {
                System.out.println( name+ " 新的进攻手段");
            }
        }
         
        SomeHero h  =new SomeHero();
        h.name ="地卜师";
        h.attack();
    }
      
}
  • 在匿名类中使用外部的局部变量

在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final

package charactor;
   
public abstract class Hero {
    public abstract void attack();
    public static void main(String[] args) {
        //在匿名类中使用外部的局部变量damage 必须修饰为final
        int damage = 5;
        //这里使用本地类AnonymousHero来模拟匿名类的隐藏属性机制
         
        //事实上的匿名类,会在匿名类里声明一个damage属性,并且使用构造方法初始化该属性的值
        //在attack中使用的damage,真正使用的是这个内部damage,而非外部damage
         
        //假设外部属性不需要声明为final
        //那么在attack中修改damage的值,就会被暗示为修改了外部变量damage的值
         
        //但是他们俩是不同的变量,是不可能修改外部变量damage的
        //所以为了避免产生误导,外部的damage必须声明为final,"看上去"就不能修改了
        class AnonymousHero extends Hero{
            int damage;
            public AnonymousHero(int damage){
                this.damage = damage;
            }
            public void attack() {
                damage = 10;
                System.out.printf("新的进攻手段,造成%d点伤害",this.damage );
            }
        }
        Hero h = new AnonymousHero(damage);
    }

8.11 默认方法

  • 什么是默认方法

默认方法是JDK8新特性,指的是接口也可以提供具体方法了,而不像以前,只能提供抽象方法

Mortal 这个接口,增加了一个默认方法 revive,这个方法有实现体,并且被声明为了default

package charactor;
 
public interface Mortal {
    public void die();
 
    default public void revive() {
        System.out.println("本英雄复活了");
    }
}

假设没有默认方法这种机制,那么如果要为Mortal增加一个新的方法revive,那么所有实现了Mortal接口的类,都需要做改动。

但是引入了默认方法后,原来的类,不需要做任何改动,并且还能得到这个默认方法

通过这种手段,就能够很好的扩展新的类,并且做到不影响原来的类

  • 为什么会有默认方法

假设没有默认方法这种机制,那么如果要为Mortal增加一个新的方法revive,那么所有实现了Mortal接口的类,都需要做改动。

但是引入了默认方法后,原来的类,不需要做任何改动,并且还能得到这个默认方法

通过这种手段,就能够很好的扩展新的类,并且做到不影响原来的类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值