Java面向对象进阶5--语法2

一、枚举

1、枚举的概述

  • 枚举是java中的一种特殊类型

2、枚举的作用:是为了做信息的标志和信息的分类。

定义枚举类的格式:

修饰符 enum 枚举名称{
    第一行都是罗列枚举类实例的名称。
}

enum Season{
    SPRING, SUMMER,AUTUMN,WINTER; 
}
/**
 * 枚举类
 */
public enum Season {
    //枚举的第一行必须罗列枚举类的对象名称,建议全部大写。
    SPRING, SUMMER,AUTUMN,WINTER;
}


//反编译后枚举的特征

public final class Season extends java.lang.Enum<Season> {
  public static final Season SPRING;
  public static final Season SUMMER;
  public static final Season AUTUMN;
  public static final Season WINTER;
  public static Season[] values();
  public static Season valueOf(java.lang.String);
  static {};
}


枚举的特征:
枚举类都是继承了枚举类型: java.lang.Enum
枚举都是最终类,不可以被继承。
构造器的构造器都是私有的,枚举对外不能创建对象。
枚举类的第一行默认都是罗列枚举对象的名称的。
枚举相当于是多例模式

3、枚举的使用场景演示

案例说明:

  • 现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号( 上下左右),以便控制玛丽移动的方向。
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.Random;

public class EnumDemo02 {
    public static void main(String[] args) {
        //1、创建一个窗口对象(桌子)
        JFrame win = new JFrame();

        //2、创建一个面板对象(桌布)
        JPanel panel = new JPanel();

        //3、把桌布垫在桌子上
        win.add(panel);


        //4、创建四个按钮对象
        JButton btn1  = new JButton("上");
        JButton btn2  = new JButton("下");
        JButton btn3  = new JButton("左");
        JButton btn4  = new JButton("右");

        //5、把按钮对象添加到桌布上去
        panel.add(btn1);
        panel.add(btn2);
        panel.add(btn3);
        panel.add(btn4);

        //6、 窗口显示
        win.setLocationRelativeTo(null);
        win.setSize(300,400);
        win.setVisible(true);


        btn1.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.UP); //让玛丽往上跳

            }
        });
        btn2.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.DOWN); //让玛丽往下跳

            }
        });
        btn3.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.LEFT); //让玛丽往左跳

            }
        });
        btn4.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move(Orientation.RIGHT); //让玛丽往右跳

            }
        });

    }
    public static void move(Orientation o){
        //控制玛丽移动
        switch (o){
            case UP:
                System.out.println("让玛丽往上飞一下~~");
                break;
            case DOWN:
                System.out.println("让玛丽往下飞一下~~");
                break;
            case LEFT:
                System.out.println("让玛丽往左飞一下~~");
                break;
            case RIGHT:
                System.out.println("让玛丽往右飞一下~~");
                break;
        }
    }
}




/**
 * 枚举类
 * 做信息标志分类
 */
public enum Orientation {
    UP, DOWN, LEFT,RIGHT;
}


①选择常量做信息标志和分类:

  • 虽然可以实现可读性,但是入参值不受约束,代码相对不够严谨。

②枚举做信息标志和分类:

  • 代码可读性好,入参约束严谨,代码优雅,是最好的信息分类技术!建议使用!

二、抽象类

1、抽象类

  • 在java中abstract是抽象的意思,可以修饰类、成员方法、
  • abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
修饰符 abstract class 类名{
       修饰符  abstract 返回值类型  方法名称(形参列表);
}

public abstract class Animal{
    public abstract void run();
}

2、注意事项:

  • 抽象方法只有方法签名,不能声明方法体。
  • 一个类中如果定义了抽象方法,这个类中必须声明成抽象类,否则报错。

3、抽象的使用场景

  • 抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。
  • 当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明为抽象类。
/**
 * 抽象类
 */
public abstract class Animal {
    /**
     * 抽象方法   有abstract 修饰  不能写方法体代码(没有中括号)
     */
    public abstract void run();
}

public class Dog extends Animal{
    @Override
    public void run() {
        System.out.println("狗跑的贼快~~");

    }
}


public class Test {
    public static void main(String[] args) {
        //目标:认识抽象类 再了解它的使用场景
        Dog  d = new Dog();
        d.run();
    }
}

总结:
①、抽象类。抽象方法是什么样的?

  • 都是用abstract修饰的,抽象方法只有方法签名,不能写方法体。
  • 一个类中定义了抽象方法,这个类必须声明成抽象类。

②、抽象类基本作用是啥?

  • 作为父类,用来被子类继承的。

③、继承抽象类有哪些要注意的?

  • 一个类继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。

4、抽象类的案例

系统需求

  • 某加油站推出了 2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另一种
    是预存5000的银卡,后续加油享受8.5折优惠。
  • 请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。

分析实现:
●创建一张卡片父类:定义属性包括主人名称、余额、支付功能(具体实现交给子类)
●创建一张白金卡类:重写支付功能,按照原价的8折计算输出。
●创建一张银卡类:重写支付功能,按照原价的8. 5折计算输出。

public abstract class Card {
    private String UserName;
    private double money;

    /**
     * 定义抽象类支付方法
     */
    public abstract void pay(double money2);





    public String getUserName() {
        return UserName;
    }

    public void setUserName(String userName) {
        UserName = userName;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}


public class GoldenCard extends Card{   //1、继承抽象类方法

    @Override        //2、重写抽象类的支付功能
    public void pay(double money2) {
          //3、计算原价8折
        double rs = money2 *0.8;
        //4、显示支付多少
        System.out.println(getUserName()+"您一共支付了:"+rs+"元");
        //5、更新账户
        setMoney(getMoney() - rs);
        //6、显示余额
        System.out.println("您的总余额剩余:"+getMoney()+"元");

    }
}


public class Test {
    public static void main(String[] args) {
        //7、调用方法实现
        GoldenCard goldenCard = new GoldenCard();
        goldenCard.setMoney(20000);
        goldenCard.setUserName("王叔叔");
        goldenCard.pay(3000);

    }
}


5、抽象类的特征、注意事项小结

特征和注意事项:

  • 类有的成员(成员变量、方法、构造器)抽象类都具备
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
  • 不能用abstract修饰变量、代码块、构造器。
  • 最重要的特征:得到了抽象方法,失去了创建对象的能力(有得有失)

6、fanal 和abstract是什么关系?

  • 互斥关系
  • abstract定义 的抽象类作为模板让子类继承,final定 义的类不能被继承。
  • 抽象方法定义通用功能让子类重写,final定义的方法子类不能重写。

7、抽象类的应用知识:模板方法模式

①什么时候使用模板方法模式

使用场景说明:当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候、

②模板方法模式实现步骤

  • 把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
  • 模板方法中不能决定的功能 定义成抽象方法让具体子类去实现。

③理解模板方法:写作文案例

需求:

  • 现在有两类学生,一类是中学生, -类是小学生,他们都要写《我的爸爸》>这篇作文。
  • 要求每种类型的学生,标题第- -段和最后一-段,内容必须-样。正文部分自己发挥。
  • 请选择最优的面向对象方 案进行设计。
import java.io.StringWriter;

public abstract class Write {
    /**
     * 正式:声明模板方法
     */
    public final void write(){   //模板呀应该用final来修饰  防止被重写  显得更专业
        System.out.println("\t\t\t\t《我的爸爸》");
        System.out.println("请说说你的爸爸:");

        //正文部分:每个子类都要写   每个子类写的情况又不一样
        //因此。模板方法把正文部分定义成抽象法方法,交给具体的子类去实现
        System.out.println(writeMain());


        System.out.println("我的爸爸简直太好了~~");
    }
    public abstract String  writeMain();

}



/**
 * //中学生类
 *
 */
public class StudentMiddle extends Write {

    @Override
    public String writeMain() {
        return "我的爸爸真是太好了~~~~~~~~";
    }
}




/**
 * 小学生类
 */
public class StudentChild extends Write {


    @Override
    public String writeMain() {
        return "我的爸爸真是太好了~~~~~~~~";
    }
}



public class Test {
    public static void main(String[] args) {
        //目标:理解模板方法模式的思想和使用步骤
        StudentChild  s = new StudentChild();
        s.write();
    }
}

模板方法建议使用final修饰的,这样会更专业,那么为什么呢?

答:模板方法是给子类直接使用的,不是让子类重写的;
一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写了模板方法,这样更安全、专业。

总结:

1、模板方法模式解决了什么问题?

  • 提高了代码的复用性
  • 模板方法已经定义了通用结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需要关心自己需要实现的功
    能即可。

三、接口

1、接口的定义与特点

  • 接口的格式如下
接口用关键字interface 来定义
    public interface 接口名{
    //常量
    //抽象方法
}
/**
 * 声明一个接口:体现一种规范;规范一定是公开的。
 */
public interface InterfaceDemo {
    //目标:接口中的成分特点:JDK8之前接口中只能有抽象方法和常量。
    //1、常量
    //注意:由于接口体现规范思想;规范都是默认公开的;所以代码层面:public abstract 可以省略不写
    String SCHOOL_NAME = "我是程序员";
    public static final String SCHOOL_NAME = "我是程序员";
    // public static final 可以省略不写

    //2、抽象方法
    //注意:由于接口体现规范思想;规范都是默认公开的;所以代码层面:public abstract 可以省略不写
    
    void run();
    //  public  abstract void run();
     void ext();
    //  public abstract  void ext();
}
  • JKD8之前接口中只能是抽象方法和常量,没有其他成分了。

2、什么是接口?

  • 接口是一种规范。

3、接口的基本使用:被实现

接口的用法: 接口是用来被类实现(implements) 的,实现接口的类称为实现类。实现类可以理解成所谓的子类。

修饰符 class 实现类 implements 接口1,接口2,接口3,...{
    
}
实现的关键字:implements
public class Test {
    public static void main(String[] args) {
        //目标:理解接口的基本使用:被类实现
        PingPongMan p= new PingPongMan("张继科");
        p.run();
        p.competition();
        p.rule();
    }
}


/**
 * 实现类
 */
public class PingPongMan implements SportMan,Law{
    private String name;

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

    @Override
    public void run() {
        System.out.println(name+"必须跑步训练!!");

    }

    @Override
    public void competition() {
        System.out.println(name+"必须参加比赛!!");

    }

    @Override
    public void rule() {
        System.out.println(name+"必须守法!!");
    }
}



/**
 * 规范
 */
public interface SportMan {
    void run();
    void competition();
}



public interface Law {
    void rule();

}

接口实现的注意事项:

  • 一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。

4、接口与接口的关系:多继承

基本小结:

  • 类与类的关系:单继承。
  • 类与接口的关系:多实现。
  • 接口与接口的关系:多继承,一个接口可以同时继承多个接口。
public class Test {
    public static void main(String[] args) {
        //目标:理解接口多继承的作用。

        BasketBallMan ballMan = new BasketBallMan();
        ballMan.rule();
        ballMan.competition();
        ballMan.eat();
        ballMan.run();
        ballMan.sleep();
    }
}


/**
 * 接口可以多继承:一个接口可以同时继承多个接口
 */
public interface SportMan extends Law,People{
    void run();
    void  competition();

}



public interface Law {
   void rule();
}



public interface People {
    void eat();
    void sleep();
}


/**
 * 实现类
 */
public class BasketBallMan implements SportMan {

    @Override
    public void rule() {
        System.out.println("必须参加比赛");

    }

    @Override
    public void eat() {
        System.out.println("必须吃东西");

    }

    @Override
    public void sleep() {
        System.out.println("必须睡觉觉");

    }

    @Override
    public void run() {
        System.out.println("必须训练");

    }

    @Override
    public void competition() {
        System.out.println("必须竞争");


    }
}



接口多继承的作用

  • 规范合并, 整合多个接口为同- -个接口,便于子类实现。

5、JDK8开始接口新增方法

JDK8开始之后,Java只对接口的成员方法进行了新增

原因如下:

第一种:默认方法

  • 类似之前写的普通实例方法:必须用default修饰
  • 默认会public修饰。 需要用接口的实现类的对象来调用
default void run(){
    Systen.out.println("开始跑");
}

第二种:静态方法

  • 默认会public修饰, 必须static修饰。
    • 注意:接口的静态方法必须用本身的接口名来调用。
static void inAddr(){
    Systen.out.println("我在快乐的学习java");
}

第三种:私有方法

  • 就是私有的实例方法:,必须使用private修饰,从JDK 1.9才开始有的。
  • 只能在本类中被其他的默认方法或者私有方法访问。
private void go(){
    Systen.out.println("准备开始学习");
}
public interface SportManInter {
    /**
     * 1、JDK8开始:默认方法(实例方法)
     *
     * --必须default修饰--,默认用public修饰
     *   默认方法属于对象才能调的  接口不能创建对象  所以这个方法只能过继给实现类  由实现类的对象调用
     *
     */
     default void run (){
         go();// 这个是私有方法  只能在内部调
         System.out.println("跑得很快~~");
    }



    /**
     * 2、静态方法
     * 必须使用static修饰  默认也会用public修饰
     *接口的静态方法,必须接口名自己调用。
     *
     */
     static void inAddr(){
        System.out.println("我们都在学习JAVA新增方法的语法~~它是java源码自己会用到的~~");
    }



    /**
     * 3、私有方法(实例方法)
     * --- JDK 1.9开始才支持的---
     * 必须在接口内部才能被访问
     */
    private void go(){
        System.out.println("开始跑~~~");
    }
}



class PingPongMan implements SportManInter{

}




class Test{
    public static void main(String[] args) {
        PingPongMan pongMan = new PingPongMan();
        pongMan.run();
        SportManInter.inAddr();  //接口的静态方法,必须接口名自己调用。
    }
}

总结:1、jDK8开始后新增了那些方法?

  • 默认方法: default修饰,实现类对象调用。

  • 静态方法: static修饰,必须用当前接口名调用

  • 私有方法: private修饰, jdk9开始才有的,只能在接口内部被调用。

  • 他们都会默认被public修饰。

  • JDK8新增的3种方法我们自己在开发中很少使用,通常是Java源码涉及到。现阶段需要理解、识别语法,明白调用关系即可。

6、使用接口的注意事项

接口的注意事项:
1、接口不能创建对象
2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。
3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。,
4、一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可。
5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值