> 文章列表 > day14_oop

day14_oop

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 {@Overridepublic 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();// 向下转型// 类转换异常,报错ClassCastExceptionDog dog = (Dog) new Animal();// 报错ClassCastExceptionDog 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设备的统一功能开启()  关闭()效果 :创建电脑对象,能插入外设,调用方法电脑开机,电脑开机前 外设启动,电脑关机前,外设先关闭