Tips:样式蚂蚁森林浇水get

java基础——day08-2 接口、多态

接口  

使用接口的注意事项

  1、接口中是没有静态代码块和构造方法的

package day09.day08_1;

public interface Myinterface {
    //错误写法
    static {
        
    }
    //错误写法
    public Myinterface(){
        
    }
}
tip1

  2、一个类只能有一个父类,但是一个类可以实现多个接口

  格式:

  public class 类名 implements 接口1,接口2{//覆盖重写所有抽象方法}

package day09.day08_1;

public interface MyinterfaceA {
    //定义抽象方法
    public abstract void methodA();
}
interfaceA
package day09.day08_1;

public interface MyinterfaceB {
    //定义抽象方法
    public abstract void methodB();
}
interfaceB
package day09.day08_1;
//实现A B接口
public class MyinterfaceImpl implements MyinterfaceA,MyinterfaceB {
    //实现类要实现多个接口中的抽象方法

    @Override
    public void methodA() {
        System.out.println("come from interface A");
    }

    @Override
    public void methodB() {
        System.out.println("come from interface B");
    }
}
ImplementsA,B
package day09.day08_1;

public class demo {
    public static void main(String[] args) {
        //定义实现类的对象
        MyinterfaceImpl duixiang = new MyinterfaceImpl();
        duixiang.methodA();
        duixiang.methodB();
    }
}
main

  3、若实现类所实现的多个接口中,存在重复抽象类,那么只需要覆盖重写一次即可

package day09.day08_1;

public interface MyinterfaceA {
    //定义抽象方法
    public abstract void methodA();
    public abstract void methodC();
}
interface-A
package day09.day08_1;

public interface MyinterfaceB {
    //定义抽象方法
    public abstract void methodB();
    public abstract void methodC();
}
interface-B
package day09.day08_1;
//实现A B接口
public class MyinterfaceImpl implements MyinterfaceA,MyinterfaceB {
    //实现类要实现多个接口中的抽象方法

    @Override
    public void methodA() {
        System.out.println("come from interface A");
    }

    @Override
    public void methodB() {
        System.out.println("come from interface B");
    }
    //A B中重复的抽象方法 实现类只需覆盖重写一次即可
    @Override
    public void methodC() {
        System.out.println("I'm live in interface-A & B");
    }
}
Implements
package day09.day08_1;

public class demo {
    public static void main(String[] args) {
        //定义实现类的对象
        MyinterfaceImpl duixiang = new MyinterfaceImpl();
        duixiang.methodA();
        duixiang.methodB();
        duixiang.methodC();
    }
}
main

  4、若实现类没有覆盖重写接口的所有抽象方法,那么实现类要是抽象类

  5、如果实现类实现的接口中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写

package day09.day08_1;

public interface MyinterfaceA {
    //定义默认方法
    public default void method(){
        System.out.println("AAA");
    }
}
interface-A
package day09.day08_1;

public interface MyinterfaceB {
    //定义默认方法
    public default void method(){
        System.out.println("BBB");
    }
}
interface-B
package day09.day08_1;
//实现A B接口
public class MyinterfaceImpl implements MyinterfaceA,MyinterfaceB {
    //此时一定要对接口中的默认方法进行覆盖重写
    @Override
    public void method() {
        System.out.println("CCC");
    }
}
Implements
package day09.day08_1;

public class demo {
    public static void main(String[] args) {
        //定义实现类的对象
        MyinterfaceImpl duixiang = new MyinterfaceImpl();
        duixiang.method();
    }
}
main

  6、一个类,如果父类中的方法接口中的默认方法产生冲突,此时优先使用父类中的方法(继承 > 接口实现)

package day09.day08_1.day08_2;

public class Test {
    public void method(){
        System.out.println("this is father's method");
    }
}
父类
package day09.day08_1.day08_2;

public interface Myinterface {
    //定义默认方法
    public default void method(){
        System.out.println("this is interface default method");
    }
}
接口--默认方法
package day09.day08_1.day08_2;

public class Myimplements extends Test implements Myinterface {

}
实现类
package day09.day08_1.day08_2;

public class demo {
    public static void main(String[] args) {
        Myimplements duixiang = new Myimplements();
        duixiang.method();
        //优先输出父类的方法
    }
}
main

多态

概述

  多态是继封装、继承后,面向对象的第三大特征

  多态的现实体现比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也
是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

定义

  多态:是指同一行为,具有多个不同表现形式。

  前提【重点】:

  1.继承或者实现【二选一】

  2.方法的重写【意义体现:不重写,无意义】

  3.父类引用指向子类对象【格式体现】

多态的体现

 1.格式

  父类名称 对象名 = new 子类名称();

  接口名称 对象名 = new 实现类名称();

package day09.day08_1.day09_1;

public class Fu {
    public void method(){
        System.out.println("父类方法");
    }
    public void methodFu(){
        System.out.println("父类特有的方法");
    }
}
Fu
package day09.day08_1.day09_1;
//子类 继承父类
public class Zi extends Fu {
    @Override
    public void method() {
        System.out.println("子类重写父类的方法");
    }
}
Zi
package day09.day08_1.day09_1;

public class demo {
    public static void main(String[] args) {
        //使用多态的写法 创建子类
        Fu obj = new Zi();
        obj.method();//因为子类有 输出子类的方法
        obj.methodFu(); //因为子类没有 调用父类的
        //此时 子类就是一个父类
    }
}
main

  注意:使用多态,代表子类就是一个父类 例如 学生 就是 一个人类的关系。

2.关于多态中的成员变量

  访问成员变量的两种形式:

  1.直接通过对象名访问成员变量:看等号左边是谁,优先用谁,没有则向上找

  2.间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

  3.编译看左边,运行还看左边

package day09.day08_1.day09_2;

public class Fu {
    int num = 10;

    public void showNum() {
        System.out.println(num);
    }
}
Fu
package day09.day08_1.day09_2;

public class Zi extends Fu {
    int num = 20;
    //测试访问成员变量会不会向下找
    int age = 16;

    //覆盖重写了 
    @Override
    public void showNum() {
        System.out.println(age);
    }
}
Zi
package day09.day08_1.day09_2;

public class demo {
    public static void main(String[] args) {
        //使用多态的写法
        Fu obj = new Zi();
        //直接方法
        System.out.println(obj.num);//发现其会指向父类
//        System.out.println(obj.age); 错误写法!
        System.out.println("==================");
        obj.showNum(); //若子类没有覆盖重写——父:10 若重写了 就是——子16
    }
}
main

3.多态中的成员方法

  多态代码中成员方法访问规则:

  1、看new的左边是谁,就优先找谁,没有则向上找。

  2、编译看左边,运行看右边

package day09.day08_1.day09_3;

public class Fu {
    public void method(){
        System.out.println("父类方法");
    }
    public void methodA(){
        System.out.println("父类特有方法");
    }
}
Fu
package day09.day08_1.day09_3;

public class Zi extends Fu {
    public void method(){
        System.out.println("子类方法");
    }
    public void methodB(){
        System.out.println("子类特有方法");
    }
}
Zi
package day09.day08_1.day09_3;

public class demo {
    public static void main(String[] args) {
        //使用多态形式
        Fu obj = new Zi();
        obj.method();   //父子都有 优先用子
        obj.methodA();  //父类特有
        //编译看左边:左边是Fu,Fu当中没有methodB方法,所以编译报错
        //obj.methodB();  //错误写法
    }
}
main

多态的好处

  实际开发中,父类类型作为方法形式参数(形参),传递子类对象给方法,进行方法的调用,更能体现多态的扩展性与便利。

 

  例如:对比 多态类定义的对象调用方法 和 普通定义的对象调用方法

 

package day09.day08_1.day09_4;
//定义一个抽象父类——动物类
public abstract class Animal {
    //定义动物类 eat()抽象方法
    public abstract void eat();
}
Animal
package day09.day08_1.day09_4;
//定义子类——猫类 继承动物类
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }
}
Cat
package day09.day08_1.day09_4;
//定义子类——狗类 继承动物类
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("吃骨头");
    }
}
Dog
package day09.day08_1.day09_4;

public class demo {
    public static void main(String[] args) {
        //使用多态方式定义 Cat Dog对象
        Animal cat = new Cat();
        Animal dog = new Dog();
        cat.eat();
        dog.eat();
        System.out.println("=======对比=========");
        //使用普通方式定义Cat Dog对象
        Cat cat1 = new Cat();
        Dog dog1 = new Dog();
        //调用showCatEat
        showCatEat(cat1);
        //调用showDogEat
        showDogEat(dog1);

    }
    public static void showCatEat(Cat cat){
        cat.eat();
    }
    public static void showDogEat(Dog dog){
        dog.eat();
    }

}
main

  多态的好处,可以使程序编写的更加简单,并具有良好的扩展性。

 引用类型转换

  多态转型分为两种:向上转型 向下转型

向上转型

  向上转型:多态本身是 子类类型 向 父类类型向上转换的过程,这个过程也是默认的。

  当父类引用 指向 子类对象时,便是向上转型。(小范围 转型 大范围)

  类似 int 转型为 double  

  使用格式:

  父类类型 变量名 = new 子类类型();

  Animal cat = new Cat();

  向上转型一定是安全的没问题的正确的,但是存在其弊端

  弊端:对象一旦向上转型为父类,那么对象无法调用子类原本特有的方法

  解决方案:用对象的向下转型【还原】

向下转型

  向下转型:父类类型 向 子类类型 向下转型的过程,是强制的

  含义:将父类对象,【还原】成为本来的子类对象。

  使用格式:

  子类类型 变量名 = (子类类型) 父类对象;

  Animal cat = new Cat(); //本来是猫 向上转型为 动物

  Cat cat = (Cat) animal; //本来是猫 还原 为猫 (向下转型)

  注意事项:

  1.必须保证对象本来创建的时候,就是子类1的对象,才能向下转型为原来的子类1对象

  2.如果对象创建的时候,不是子类1的对象,现在非要转型为子类1的对象,就会报错。(只有创建时为同类型的 才能向下转型)

  其含义可以理解为:

  int num = (int)10.0 //可以

  int num = (int)10.5 //不可以 精度损失

  例如:

package day09.day08_1.day09_4;
//定义一个抽象父类——动物类
public abstract class Animal {
    //定义动物类 eat()抽象方法
    public abstract void eat();
}
Animal-父类
package day09.day08_1.day09_4;
//定义子类——猫类 继承动物类
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }
    //定义特有方法 抓老鼠
    public void catchMoise(){
        System.out.println("抓老鼠");
    }
}
Cat - 子类
package day09.day08_1.day09_4;
//定义子类——狗类 继承动物类
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("吃骨头");
    }
}
Dog-子类
package day09.day08_1.day09_4;

public class demo {
    public static void main(String[] args) {
        //使用多态方式定义 Cat Dog对象
        Animal animal = new Cat(); //本来创建的时候是一只猫
        Animal dog = new Dog();
        animal.eat(); //正确
//        animal.catchMoise(); 错误! 多态创建的对象 不能访问自己独有的方法

        //向下转型 进行还原
        Cat cat1 = (Cat)animal;
        cat1.catchMoise();
    }

}
main

判断对象本来是什么子类——Instanceof

  1.问题:如何知道一个父类引用的对象,本来是什么子类?

  2.解决:使用Instanceof关键字,给引用变量做类型校验

  3.格式:对象 instanceof 数据类型  //会得到一个boolean结果 

package day09.day08_1.day09_4;
//定义一个抽象父类——动物类
public abstract class Animal {
    //定义动物类 eat()抽象方法
    public abstract void eat();
}
Animal--父类
package day09.day08_1.day09_4;
//定义子类——猫类 继承动物类
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }
    //定义特有方法 抓老鼠
    public void catchMoise(){
        System.out.println("抓老鼠");
    }
}
Cat类
package day09.day08_1.day09_4;
//定义子类——狗类 继承动物类
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("吃骨头");
    }
    public void seeHouse(){
        System.out.println("看家");
    }
}
狗类
package day09.day08_1.day09_4;

public class demoInstenceof {
    //如何知道一个父类引用的对象,本来是什么子类
    //
    public static void main(String[] args) {
        Animal animal = new Dog(); //买了狗
        giveMePet(animal);

    }
    //当女朋友说随便买宠物 判断女朋友到底想要什么宠物
    public static void giveMePet(Animal animal){
        //如果是狗 尽其职 看家
        if(animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.seeHouse();
        }
        //如果是猫 尽其职 抓老鼠
        if(animal instanceof Cat){
            Cat cat = (Cat)animal;
            cat.catchMoise();
        }
    }
}
判断——到底是什么类

  Tip:通过判断后,使用向下转型更安全

练习:接口多态的综合案例

question:笔记本电脑(laptop)通常具备使用USB设备的功能。在生产时,笔记本都预留了可以插入USB设备的USB接口,但具体是什么USB设备,笔记本厂商并不关心,只要符合USB规格的设备都可以。

  定义USB接口,具备最基本的开启功能和关闭功能。鼠标和键盘要想能在电脑上使用,那么鼠标和键盘也必须遵守USB规范,实现USB接口,否则鼠标和键盘的生产出来也无法使用。

分析:

  1.usb接口,包含打开和关闭功能

  2.笔记本类,包含运行、关机、使用USB设备功能

  3.鼠标类,要实现USB接口,并具备点击方法

  4.键盘类,要实现USB接口,并具备敲击的方法

package day09.day08_1.day09_5;

public interface USB {
    public abstract void open();
    public abstract void close();
}
USB接口
package day09.day08_1.day09_5;

public class Mouse implements USB {
    @Override
    public void open() {
        System.out.println("鼠标开启,红灯闪一闪");
    }

    @Override
    public void close() {
        System.out.println("鼠标关闭,红灯熄灭");
    }
    //定义点击方法
    public void click(){
        System.out.println("鼠标单击");
    }
}
鼠标实现类
package day09.day08_1.day09_5;

public class keyBoard implements USB {
    @Override
    public void open() {
        System.out.println("键盘开启,绿灯闪一闪");
    }

    @Override
    public void close() {
        System.out.println("键盘关闭,绿灯熄灭");
    }
    //定义敲击方法
    public void hit(){
        System.out.println("键盘敲击");
    }
}
键盘实现类
package day09.day08_1.day09_5;

import javax.swing.*;

public class Computer {
    //电脑开机运行功能
    public void run(){
        System.out.println("电脑已开始运行");
    }
    //定义电脑关机
    public void shutdown(){
        System.out.println("电脑关机");
    }
    public void useUsb(USB usb){
        if(usb != null){
            usb.open();
            //类型转换,调用特有方法
            if(usb instanceof Mouse){
                Mouse mouse = (Mouse) usb;
                mouse.click();
            }
            if(usb instanceof keyBoard){
                keyBoard kb = (keyBoard)usb;
                kb.hit();
            }
            usb.close();
        }
    }
}
电脑类
package day09.day08_1.day09_5;

import javax.swing.*;

public class demo {
    public static void main(String[] args) {
        Computer computer = new Computer();
        //开启电脑
        computer.run();

        //创建鼠标实体对象
        Mouse mouse = new Mouse();
        //接入鼠标并点击
        computer.useUsb(mouse);

        //创建键盘实体对象
        keyBoard jp = new keyBoard();
        //接入键盘并敲击
        computer.useUsb(jp);

        //关机
        computer.shutdown();
    }
}
main

 

posted @ 2021-03-09 22:48  心岛未晴  阅读(51)  评论(0)    收藏  举报