Day8.抽象类和接口

抽象类和接口

技能目标:

​ 掌握抽象类和抽象方法

​ 掌握接口的用法

​ 理解面向对象的设计原则

1.1初始抽象类和抽象方法
1.区分普通方法和抽象方法

在Java中,当一个类的方法被abstract关键字修饰的时候,被称为抽象方法。抽象方法所在的类必须定义为抽象类。

当一个方法被定义为抽象方法后,意味着该方法不会有具体的实现(没有方法体)。而是在抽象类的子类中通过方法重写进行实现,定义抽象方法的语法格式:

[访问修饰符] abstract<返回类型> <方法名>([参数列表]);

普通方法和抽象方法的相比,主要有两点区别:

​ a.抽象方法需要用abstract修饰,普通方法不需要

​ b.普通方法有方法体,抽象方法没有方法体

2.区分普通类和抽象类

在java中,当一个类被abstract关键字修饰时,该类被称为抽象类.

​ 定义抽象类的语法格式:

​ abstract class <类名>{

​ }

普通类和抽象类的区别:

​ 1.抽象类需要abstract 修饰,普通类不需要

​ 2.普通类可以实例化,抽象类不能实例化

3.定义一个抽象类

当一个类被定义为抽象类,它可以包含各种类型的成员,包括属性、方法,其中方法又分为普通方法和抽象方法。

抽象类的结构:

​	public abstract  class 类名称{

​		访问修饰符 返回类型 方法名(){

​			方法体

​		}

​	}
注意:

​ 抽象方法只能定义在抽象类,但是抽象类中可以包含抽象方法,也可以包含普通方法,还可以包含普通类的一切成员

1.2使用抽象来描述抽象的事物

例:

分析:不可以直接实例化咱们的抽象类,但是它的子类是可以实例化,如果子类中没有重写pirnt(),子类将继承
父类Pet的该方法,默认调用父类的print()方法

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 14:31
 * @TODO
 */
public abstract class Pet {
    private String name="无名氏";
    private int health=100;
    private int love=0;



    public Pet(String name){
        this.name=name;
    }

//    public void print(){
//        System.out.println("宠物的自白:\n我的名字叫"+this.name+",健康值"+this.health+",和主人的亲密度"+love);
//
//    }
    public abstract void print();
}

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 14:39
 * @TODO
 */
public class Dog extends Pet {


    private String strain;//品种

    public Dog(String name, String strain) {
        super(name);
        this.strain = strain;
    }

    public void print() {
        System.out.println("我是一只什么狗:" + strain);
    }
}

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 14:36
 * @TODO
 */
public class Test1 {
    public static void main(String[] args) {

//        Pet pet=new Pet();抽象类不能实例化

        Dog dog=new Dog("狗狗","小黄");
        dog.print();
    }
}

在这里插入图片描述

1.3初始接口
1.生活中的接口

在现实生活中,USB接口实际上是某些企业和组织制定的一种约定或标准,规定了接口的大小,形状等。按照该约定设计的各种设备,如U盘、USB风扇、USB键盘都可以插到USB接口上正常工作。USB接口相关工作是按照如下步骤进行的。

​ a.约定USB接口的标准

​ b.制作符合USB接口约定的各种具体设备

​ c.把USB设备插到USB接口上进行工作

​ Java中接口的作用和生活中的接口类似,它提供了一种约定,使得实现接口的类(或结构)在形式上保持一致。

​ 如果抽象类中所得方法都是抽象方法,就可以使用Java提供的而接口来表示。从这个角度来讲,接口可以看作一种特殊的“抽象类”,但是采用与抽象类完全不同的语法表示,两者的设计理念也不同。

2.定义和实现一个简单的接口

通俗的来说,接口是一个不能实例化的类型,接口类型的定义的语法格式:


public interface 接口名{
​	
     //接口成员

​}

和抽象类的不同:定义接口使用的关键是interface修饰,访问修饰符只能是public

​ 接口中的成员可以是全局常量和公共的抽象方法。

实现接口的语法 :



​	public   类名   implements 接口名{

​		实现方法

​		普通方法

}

a.实现接口使用implements关键字

​ b.实现接口的类必须实现接口中定义的所有的抽象方法。接口的实现类允许包含普通的方法。

3.更复杂的接口

​ 接口本身也可以继承接口

​ 接口继承的语法格式:


​	【访问修饰符】 interfance 接口名  extends 父类接口1,父接接口2,...{

​			常量的定义

​			方法的定义

​	}

一个普通类只能继承一个父类,但是能同时实现多个接口,也可以同时继承抽象类和实现接口:

实现多接口的语法格式:



​		class  类名   extends  父类名   implements  接口1,接口2,...{


​	}

接口:

package Test3;

public interface UsbInterface {

    public void service();

}

实现类:

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:18
 * @TODO
 */
public class UDisk implements UsbInterface{
    @Override
    public void service() {
        System.out.println("连接数据接口,开始传输");
    }

}

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:22
 * @TODO
 */
public class UsbFan implements UsbInterface {

    @Override
    public void service() {
        System.out.println("连接成功,风扇开始转动");
    }
}

测试:

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:19
 * @TODO
 */
public class Test2 {
    public static void main(String[] args) {

        //实例化接口的实现类(UDisk()),可以返回接口的实例化对象,
        //这个也是Java多态的一种应用
        UsbInterface usbInterface= new UDisk();
        usbInterface.service();


        UsbInterface usbInterface1=new UsbFan();
        usbInterface1.service();
    }
}

在这里插入图片描述

注意:

​ 关于定义和实现接口所要注意的地方

​ 1.接口和类、抽象类是一个层次的概念,命名规则相同

​ 2.修饰符如果是public ,则该接口再整个项目中可见,如果省略修饰符,该接口只在当前包中可见

​ 3.接口中可以定义常量,不能定义变量,接口中的属性都默认用"public static final",即接口中的属性都是静态全局常量,接口中的常量必须在定义时给定初始值:

​ public static final int =3.14

​ int PI =3.14//在接口中,这两个定义语句效果相同

​ int PI;// 在接口中定义必须赋值初始化

​ d.接口中所有的方法都是抽象方法,接口中的方法默认时public

​ c.和抽象类一样,接口不能实例化,接口中不能有构造方法

​ e.类中只能继承一个父类,但是可以通过implements实现多个接口,一个类必须实现接口的全部方法,

否则必须定义为抽象类,若一个类在继承父类的同时又实现了多个接口,extends必须位于implements之前

案例:实现愤怒的小鸟

鸟叫接口:

package Test3;

public interface ShoutAbility {
    public void shout();
}

嗷嗷叫实现类

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:34
 * @TODO
 */
public class AoShout implements ShoutAbility{
    @Override
    public void shout() {
        System.out.println("嗷嗷叫");
    }
}

喳喳叫

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:35
 * @TODO
 */
public class ZhaShout implements ShoutAbility{
    @Override
    public void shout() {
        System.out.println("喳喳叫");
    }
}

鸟类

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:36
 * @TODO
 */
public  abstract class Bird {


    //接口也是一个引用类型
    ShoutAbility shoutAbility;


    public Bird(ShoutAbility shoutAbility) {
        this.shoutAbility = shoutAbility;
    }

    //叫的行为
    public void shout(){
        shoutAbility.shout();
    }
    //飞行
    public void fly(){
        System.out.println("弹射");
    }
    public void attack(){

    }
}

爆炸鸟:

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:39
 * @TODO
 */
public class BoomBird extends Bird{

    public BoomBird(ShoutAbility shoutAbility) {
        super(shoutAbility);
    }

    //重写攻击方法
    public void attack(){
        System.out.println("弹射攻击");
    }
}

分裂鸟

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:40
 * @TODO
 */
public class SplitBird extends Bird{
    public SplitBird(ShoutAbility shoutAbility) {
        super(shoutAbility);
    }

    @Override
    public void attack() {
        System.out.println("分裂攻击");
    }
}

测试

package Test3;

/**
 * @作者:Xem626
 * @date: 2022/7/13 15:40
 * @TODO
 */
public class Test {
    public static void main(String[] args) {


        AoShout aoShout = new AoShout();
        ZhaShout zhaShout = new ZhaShout();

        BoomBird boomBird=new BoomBird(zhaShout);
        SplitBird splitBird=new SplitBird(aoShout);

        boomBird.shout();
        boomBird.attack();
        splitBird.shout();
        splitBird.attack();


    }
}

在这里插入图片描述

1.4面向对象设计的原则

在实际开发过程中,遵循以下原则,会让代码更具灵活性,更能适应变化。
1.摘取代码中变化的行为,形成接口
例如,在“愤怒的小鸟”游戏中,鸟叫的行为变化性很大,有的鸟叫,有的鸟不叫。各种鸟的叫声也不一样,这种行为最好定义为接口。

2.多用组合,少用继承
在“愤怒的小鸟”游戏中,通过在抽象类鸟中包含鸟叫的属性来实现组合,有效地减少了代码冗余。

3、针对接口编程,不依赖于具体实现
如果对一个类型有依赖,应该尽量依赖接口,尽量少依赖子类。因为子类一旦变化代码变动的可能性大,而接口要稳定得多。在具体的代码实现中,体现在方法参数尽量使用接口,方法的返回值尽量使用接口,属性类型尽量使用接口等。

4.针对扩展开放,针对改变关闭
如果项目中的需求发生了变化,应该添加一个新的接口或者类,而不要去修改原有的代码。
需要说明的是,这4个面向对象的原则比较抽象,可以先记住它,然后在实际的面向对象开发中尝试应用这些原则,然后加深对这些原则的理解。

本章总结:

​ 1.抽象方法使用abstract 修饰符,没有方法体。

​ 2.抽象类使用abstract 修饰,不能被实例化

​ 3.类只能继承一个类,但是可以实现多个接口。一个类要实现接口的全部方法,否则必须定义为抽象类

​ Java通过实现多个接口达到多重继承效果

​ 4.接口表示一定约定,也表示一种功能,体现了约定和实现分离的原则。通过面向接口编程,可以降低代码之间的耦合性,提高代码的可扩展性,可维护性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xem626

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值