day14_oop

今日内容

零、 复习昨日
一、作业
二、向下转型
三、抽象
四、接口

零、 复习昨日

  • final

    • 修饰类,不能被继承
    • 修饰方法,方法不能重写
    • 修饰变量/属性, 变成常量
  • static

    • static 修饰类(内部类),属性,方法
    • 修饰的属性和方法,称为类属性,类方法,因为这些属性方法属于类不属于对象,也是因为静态属性和静态在内存只有一份,被该类的所有对象共享
    • 静态属性和方法随类加载而初始化,所以它可以通过类名直接调用
    • 静态方法只能调用静态方法和静态属性(静态只能调用静态)
    • 静态方法内不能调用this

总结:static应用

  • 当有些属性需要被共享时就设置static

  • 当有些方法需要被频繁调用,为了方便使用,设置静态

  • 综合使用

    • 为经常配合final一起修饰常量, 静态常量
    • public static final double PI = 3.1415926…;
    • public static final 顺序无所谓,但是建议按public static final顺序
  • 多态

    • 是指方法执行出现的多态效果
    • 前提
      • 继承/实现
      • 重写
      • 向上转型(父类引用指向子类对象)
      • Animal animal = new Dog();
    • 编译看父类,运行看子类
  • 应用场景:

    • 方法参数列表设计成父类型参数,调用时传入子类对象

    • 为了存储同一大类型的属性,将数组定义为父类型的数组,但是数组中存储的是子类对象

    • 方法的返回值类型是父类类型,返回值是子类类型

    •     public static MyAnimal getInstance(){
              return new MyCat();
              // return new MyDog();
          }
      
          public static void main(String[] args) {
              MyAnimal instance = getInstance( );
              instance.eat();
          }
      

一、作业

设计一个合理的程序:有一个灯泡(Bulb)类.灯泡有发光的方法,
		他有两个子类,分别是红灯泡和绿灯泡;
		还有一个台灯(TableLamp)类,他有一个开灯的方法,实现开红灯,红灯亮,发红光,开绿灯,绿灯亮,发绿光;
public class Bulb {
    public void light(){
        System.out.println("灯泡发亮" );
    }
}
public class RedBulb extends Bulb {
    @Override
    public void light() {
        System.out.println("红灯泡,发红光");
    }
}
package com.qf.homework2;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 台灯
 */
public class TableLamp {

    public void open(Bulb bulb){
        bulb.light();
    }

    // public void open(RedBulb redBulb){
    //     redBulb.light();
    // }
    // public void open(GreenBulb greenBulb){
    //     greenBulb.light();
    // }
    // public void open(PinkBulb pinkBulb){
    //     pinkBulb.light();
    // }

    public static void main(String[] args) {
        // 买台灯
        TableLamp tableLamp = new TableLamp( );

        // 买灯泡
        RedBulb redBulb = new RedBulb( );
        GreenBulb greenBulb = new GreenBulb( );
        PinkBulb pinkBulb = new PinkBulb( );
        BlackBulb blackBulb = new BlackBulb( );

        // 装入灯泡,开灯
        tableLamp.open(blackBulb);
    }
}

二、向上转型&向下转型

父类引用指向子类对象 : 向上转型

什么时候需要向上转型? 在需要使用多态效果时向上转型

向下转型: 只有先向上的父类引用才能向下转为子类对象

    public static void main(String[] args) {
        // 向上转型
        Animal animal = new Dog();
        animal.eat();

        // 向下转型
        // 类转换异常,报错ClassCastException
        Dog dog = (Dog) new Animal();// 报错ClassCastException
        Dog dog2 = (Dog) animal; // 正常,可以转换

    }

为什么要向下转型?

  • 当需要使用子类特有的方法时
    public static void show() {
        Animal[] animals = new Animal[2];
        animals[0] = new Dog();
        animals[1] = new Cat();

        // 展示
        for (int i = 0; i < animals.length; i++) {
            Animal animal = animals[i];
            animal.eat();
            if (animal instanceof Dog) {
                Dog dog = (Dog)animal;
                dog.watchHome();
            } else if (animal instanceof Cat) {
                Cat cat = (Cat)animal;
                cat.catchMouse();
            }
        }
    }
}

三、抽象类

抽象: 看不懂,看着不太像,不具体的看不明白

抽象类: 使用abstract修饰的类是抽象类 (抽象类中有的方法是抽象的看不懂…)

3.1 语法

package com.qf.oop2;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public abstract class Animal {

    // 报错,属性不需要抽象
    // abstract int age;

    int age;

    /**
     * 1 抽象方法没有方法体
     * 2 抽象方法需要使用abstract修饰
     * 3 抽象方法需要放在抽象类中
     * 4 抽象类需要使用abstract
     * 5 抽象类中可以有正常方法
     * 6 抽象类也可以没有抽象方法
     * 7 抽象类中有构造方法,但是不能直接new对象
     *   而是子类构造时会调用抽象父类构造方法,初始化父类对象
     * 8 抽象类是用来被继承的
     * --------------------
     * 9 子类继承抽象类,要么子类也变成抽象类,
     *                 要么实现所有抽象方法
     *   实现? 重写方法,让方法能真正的执行
     */
    abstract void eat();

    public void move(){
        System.out.println("动物移动" );
    }

    public Animal(){
        System.out.println("Animal()" );
    }
}

3.2 使用场景

之前练习的各种继承多态的题,父类方法都可以变成抽象方法和抽象类

练习: 改造灯泡练习题,将父类改造成抽象类和抽象方法即可

练习: 改造形状练习题,将父类改造成抽象类和抽象方法即可

总结: 抽象类应用就是一种约束的效果,是一种限制,子类一旦继承父类,就必须要重写方法

用法总结:

  • 使用到别人的抽象类,继承后要重写方法
  • 当设计程序时,有些类需要被子类继承且必须重写方法时,就把父类设计成抽象

抽象类是用来抽象差异性、具体共同点的。也就是将差异性方法抽象化,提供给子类用于重写。共同的方法具体化,所有子类继承。


把子类不一样的方法抽象成抽象方法,每个子类都重写
把子类都一样的方法提取到父类,每个子类直接用,不用重写

四、接口

4.1 语法

引用数据类型: 数组,类,接口

接口不是类,比抽象类还抽象的一种java文件

  • 接口不是类,使用的interface修饰的

  • 接口中没有属性,所有属性都是常量,默认被public static final修饰

  • 接口中没有正常方法,所有方法都是抽象的,默认都被public abstract修饰

  • 接口中没有构造方法,不能创建对象的.

  • 接口主要是用来被子类实现implements

  • 子类实现接口,就必须重写所有抽象方法,否则就要将自己定义成抽象类

  • 子类允许多实现接口,用逗号隔开

  • 子类允许继承的同时再实现接口

  • public class UDisk extends Electron implements USB , Disk{}
    
  • 接口之间允许继承,且允许多继承(类不允许多继承)

4.2 应用

与抽象类用处基本一致,用在多态的场景
USB use = new UDisk();

改造了灯泡类为接口

改造了形状为接口

4.3 总结

接口是一种能力的体现

接口是一种规范/约定


接口即是设计:在设计层面,接口可以避免我们陷入对细节的过多思考,
可以让我们站在一个更高的视角对系统做更好的评估,比如系统的交互
设计是否合理,功能是否缺失,是否具备可行性,是否过于复杂等等。

public boolean login(String username,String password);
接口即是约定:在编码层面,接口可以明确的告诉开发人员如何使用
(接口的语义,需要什么作为输入,会有什么输出),而开发人员只
需要根据这些约定去实现具体的功能代码即可。

4.4 经验

对于以后写代码,该怎么设计?

  • 很多类有公共的属性,方法的抽取成父类来继承
  • 有些类中的方法被抽取到父类中,但是子类又不合适还需要重写,那就把类和方法定义成抽象
  • 将一些功能性的行为定义成接口,让想拥有这些功能的类去实现即可

五、练习

		设计程序 : 
			电脑类的属性 : 有多个usb插口
			电脑类的功能 : 
				1) 通过接口插入外设 (u盘,麦克风,键盘等)
				2) 开机
					要求: 电脑开机前,先启动外设
				3) 关机
					要求: 电脑关机前,先关闭外设
			外设类(u盘,麦克风,键盘等)
				功能 : 启动  关闭
			USB接口
				定义usb设备的统一功能
					开启()  关闭()
		效果 :
			创建电脑对象,能插入外设,调用方法电脑开机,电脑开机前 外设启动,
			电脑关机前,外设先关闭
		

你可能感兴趣的:(#,Java2307,java,jvm,javascript)