(八)面向对象多态与接口的概括

本文详细介绍了Java中的接口和多态特性。接口作为规范的约定,实现了多继承并降低了模块间的耦合度。多态允许一个引用类型调用不同对象的相同方法,展现不同形态。通过面向接口编程,可以实现更灵活的设计,增加系统的可扩展性和维护性。文章还通过示例解释了接口的实现、多态的操作以及类型转换,强调了多态带来的好处。
摘要由CSDN通过智能技术生成

面向对象(三)

1.接口
2.多态
3.多态中的类型转换
4.多态的好处


接口

定义与多继承性

接口时一种约定的规范,是多个抽象方法的集合

  • 接口中的方法时抽象方法,并不提供功能实现,体现了规范和实现相分离的思想
  • 接口不能创建对象,接口不存在构造方法
  • 接口体现了低耦合思想(接口用于模块间的解耦)
所谓耦合度,表示组件之间的依赖关系。
依赖关系越多,耦合性越强,同时表明组件的独立性越差
  • 接口可以被认为是一种特殊的类,定义接口使用interface关键字
public interface 接口名{
    //抽象方法1();
    //抽象方法2();
    //抽象方法3();
}
  • 接口表示具有某些功能的事物,接口名使用名词 ,一般以I开头

定义走路接口

public interface IWalkable {
    public void walk();
}

注意: 接口中的方法都是公共的抽象方法

写法
  1.  public abstract void foo();
  2. void print(); //默认省略了public
  3.  public void showInfo();  //推荐写法

4.从Java8开始, Java支持在接口中定义有实现的方法(这里先不讲,避免概念混淆)


在java中,接口也可以继承,一个接口可以继承多个接口(多继承)

  • 定义行走规范
public interface IWalkable {  public void walk(); }
  • 定义游泳规范
public interface ISwimable { public void swim(); }
  • 两栖动物,能走能游泳
public interface IAmphibiable extends IWalkable,ISwimable{
}
 //同时继承了两个接口 ,子类继承了父接口的所有方法


接口实现类

我们定义接口时,方法是抽象的,并没有方法体,前面讲到接口是不能创建对象的,所以我们需要去定义一个类去实现这个接口,并且必须实现接口中所有的抽象方法,我们称接口实现类.

格式:

public class 类名 implements 接口名{
//实现接口中抽象方法
}
接口与实现类的关系:
1.接口:定义多个抽象方法,仅定义不提供实现
2.实现类:实现接口,实现接口中所有的抽象方法,完成具体功能的实现    

例子:前面已经定义了IWalkable接口,ISwimable接口

定义人类Person实现类

/*
*person作为IWalkable的实现类,必须实现接口中所有的抽象方法
* => 接口约束实现类必须实现 walk() 方法
* => 实现类 has a 接口
* => 实现类具有接口中定义的功能
* => 接口约定了实现类应该具备的功能
* */
public class Person implements IWalkable{
    @Override
    public void walk() {
        System.out.println("人类在步行");
    }
}


1.实现类可以继承父类,同时也可以实现一个或多个接口,继承在前,实现在后

2.接口是一种引用数据类型,可以用来声明变量,并接收(引用)所有该接口的实现类对象。

  • 创建实现类对象
接口 变量 = new 实现类(); 

定义青蛙类(Frog),继承动物类(Animal),实现走路,游泳(前面两个接口)

Animal类

public abstract class Animal {
    public abstract void sleep();=
}

Frog类

public class Frog extends Animal implements ISwimable,IWalkable{
    @Override  
    public void sleep() {
        System.out.println("青蛙在睡觉"); //覆盖了父类的抽象方法
    }
    @Override
    public void swim() {
        System.out.println("青蛙会游泳");//实现游泳接口方法
    }
    @Override
    public void walk() {
        System.out.println("青蛙会走路");//实现走路接口方法
    }
}

测试类

public class Test01 {
    public static void main(String[] args) {
        Frog f1 = new Frog(); //创建对象f1
        f1.sleep(); //f1调用覆盖后的方法sleep()
        f1.swim(); //f1调用覆盖后的方法swim()
        
        IWalkable walkable = null; //声明一个接口类型的变量
        walkable = new Frog();   //接口可以引用其实现类对象
        walkable.walk();

        
        总结:
        1.当我们声明一个接口类型的变量时,它表示的意义是希望它的实现类应该具备什么功能
        2.重心在于实现类,能不能满足接口约定的功能,重心不在于持有数据,从而不依赖于任何某种特定类型的对象,进而对两个模块的功能进行解耦
        
    }
}


- 接口在实际开发过程中用于两个模块/组件的解耦,降低耦合度
=>未来在架构师眼里,模块和模块之间的衔接都使用接口,
=> 架构师眼里只有接口,我们称为面向接口编程

  • 接口表示一种规约(规范、标准),它里面定义了一些列抽象方法(功能),它可以被多个类实 现

  • 面向接口编程,体现的就是多态,其好处:把实现类对象赋给接口类型变量,屏蔽了不同实现类之 间的实现差异,从而可以做到通用编程。


多态

面向对象三大特征:封装,继承,多态


什么是多态?

所谓多态,表示的是一个对象具有多种形态.

  • 当同一引用类型变量调用同一方法时,由于引用实例不同,方法产生的结果不同,结果呈现多种形态/状态,这种情况在oop中称为多态

  • 当编译时类型和运行时类型不一致时,就会出现多态

  • 编译时类型:声明对象变量的类型,编译类型必须是运行类型的父类或接口

  • 运行时类型:对象的真实类型

多态发生的条件
  1. 必须继承
  2. 必须重写
  3. 多态建立在重写/实现的基础上

例子;

Animal animal =null;//声明时的类型称为编译类型
animal = new Dog();//运行时类型 new Dog()


多态操作

继承关系

父类引用变量指向于子类对象(父引子),调用方法时实际调用的是子类的方法。

父类 变量名 = new 子类();
变量名.方法();
实现关系

接口引用变量指向实现类对象,调用方法时实际调用的是实现类实现接口的方法。

接口 变量名 = new 实现类();
变量名.方法();

//     接口new实现类可以实现多态

例子:

public class Test01 {
    public static void main(String[] args) {
        Animal animal =null;   //声明时的类型称为编译类型   
        animal = new Dog();   //运行时类型 new Dog()

        
    Animal animal1 = new Dog();//可以使用父类 引用 子类实例
    Animal animal2 = new Cat(); //父类表示更大的群体

        /*
        *1.父类对象可以引用子类实例(父引子)
        *2.当编译时类型和运行时类型不一致时,就会出现多态
        *3.编译时类型只能看到自己定义的方法,看不到子类自己特有的方法(不可见)
        * */
    }
}


多态对象调用方法问题

当把子类赋给父类变量时,调用方法

Animal a1 =new Dog(); 
a1.shout(); 

此时a1调用的方法是来自父类还是子类呢?

1.编译时,会先去找父类方法,父类方法存在,会在运行时期找子类方法,子类方法存在运行子类的,没有就会运行父类的方法
2.如果编译的时候没有找到父类方法,那么就会编译报错了   


多态中的类型转换


类型转换

自动类型转换:把子类对象赋给父类变量(多态)

Animal a = new Dog();
Object obj = new Dog(); //Object是所有类的根类

强制类型转换:把父类类型对象赋给子类类型变量。

子类类型 变量 = (子类类型)父类对象;
对象的真实类型应该是子类类型

如果需要调用子类特有的方法时, 一定要进行强制类型转换。

public class Test01 {
    public static void main(String[] args) {
        Animal animal = new Dog();
        //想调用Dog独有的方法,把animal强转成Dog类型
        animal=(Dog)animal;
        Dog dog = (Dog)animal; //强转
        dog.eat();
        System.out.println(animal instanceof Dog); 
    }
}


instanceOf

instanceOf运算符:判断该对象是否是某一个类/接口的实例

语法:

boolean b = 对象A instanceof 类B; //判断 A对象是否是 B类的实例?如果是,返回true


多态的好处

多态:同一个对象,在不同时刻体现出来的不同状态。
能都有规范的划分区域,如果需要添加新的业务需求,
我们只需实现某个接口,就可以实现功能,其中展示了多态的功能,有延展性
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值