JAVA笔记08

本文主要探讨Java中的接口使用,包括多实现、方法优先级以及内部类的详细讲解,如局部内部类、匿名内部类的特性和应用场景。同时,重点介绍了多态的前提条件,以及如何避免类型转换异常。
摘要由CSDN通过智能技术生成

回顾:
权限修饰符: public -> protected -> (default) ->private
重写:
1.方法名和参数列表一致
2.子类中重写的方法, 返回值类型[小于等于]父类返回值类型(如父类方法是public,子类就是public或是protected或是默认default)
3.权限修饰符,[大于等于]父类方法的权限
final:
类: 类不能被继承
方法: 方法不能被重写
变量: 常量, 不能被修改, 必须初始化
常见的final类:
String Math
String不可变的: CharSequence - 字符序列 - 字符数组
底层实现: 字符数组 -> 字节数组 byte[] value
final value = 其他值
String str = “hello”;
str = “hi”;

1.1 接口:

1.公共的抽象方法
2.公共的静态常量 public static final
3.公共的默认方法
4.公共的静态方法[私有的]
5.私有的方法

1.1.1使用接口:

实现类 implements 接口
实现所有的抽象方法, 默认方法[可以选择性重写]
创建实现类对象, 调用方法

类和接口叫做多实现, 要重写/覆盖[实现]所有的口的所有抽象方法和重复的默认方法

package Demo1001;
//接口类
public interface Interface01 {
     void abstractmethod();
     void abstractmethod01();
}

package Demo1001;
//实现类
public class Imply implements Interface01{
    @Override
    public void abstractmethod() {
        System.out.println("001");
    }

    @Override
    public void abstractmethod01() {
        System.out.println("002");
    }
}

类和类叫做单继承, 父类中的方法和父接口中的默认方法重复了, 优先调用父类中的方法:
Zi extends Fu implements InterfaceA
Fu和InterfaceA中的方法重名,优先调用Fu中的方法

接口作为方法参数, 接口作为返回值:
具体使用的都是接口的实现类对象

package Demo1001;
//主类
public class Demo1001 {
    public static void main(String[] args) {
        Imply impl = new Imply();
        impl.abstractmethod();
        impl.method01();
        Demo10011 cc = new Demo10011();
        cc.h(impl);
    }
}


package Demo1001;
//接口作为返回参数
public class Demo10011{
    public static Interface01 h(Interface01 a){
        a.abstractmethod();
//        Interface01 a1 = new Imply();
//        return  a1;
        return new Imply();
    }

}


package Demo1001;
//实现类
public class Imply implements Interface01{
    Imply(){
        System.out.println("OOO");
    }
    @Override
    public void abstractmethod() {
        System.out.println("001");
    }

    @Override
    public void abstractmethod01() {
        System.out.println("002");
    }
}



package Demo1001;
//接口类
public interface Interface01 {
     void abstractmethod();
     void abstractmethod01();

     public default void method01(){
         System.out.println("AAA");
         method03();
     }
     static void method03(){
         System.out.println("BBB");
         System.out.println("CCC");
     }

}


//OOO
//001
//AAA
//BBB
//CCC
//001
//OOO

1.2多态的前提:

class MyInterfaceAImpl extends Object implmenets MyInterfaceA
MyInterfaceA a = new MyInterfaceAImpl() -> 向上造型
Object o = new MyInterfaceAImpl() -> 向上造型
Fu fu = new Zi();
Animal a = new Cat();

父类型引用 指向 子类型对象 -> 向上造型
父类型 a = new 子类型对象();
接口类型 a = new 实现类对象();

编译器 看 = 左边类型, 运行时JVM 看 = 右边类型

package Demo1002;
//主类
public class Main {
    public static void main(String[] args) {
        //父类型引用 指向 子类型
        //Demo10Fu fu = new Demo10Fu();
        Demo10Fu fu = new Dem10Zi();
        Dem10Zi zi = (Dem10Zi) fu;
        //Dem10Zi zi = new Dem10Zi();

        fu.m1();
        //编译看左边,fu中的变量
        System.out.println(fu.age);
        //运行看右边,子类中的重写方法
        System.out.println(fu.getAge());
        //fu.m3();
        zi.m3();
        fu.m4(zi);
    }
}

package Demo1002;
//父类
public class Demo10Fu {
    int age = 10;

    public void m1(){
        System.out.println("Fu m1方法");
    }

    public int  getAge() {
        return age;
    }
    public Demo10Fu m4(Demo10Fu a){
        System.out.println("JJJ");
        return null;
    }
}


package Demo1002;
//子类
public class Dem10Zi extends Demo10Fu{
    int age = 20;
    public int  getAge() {
        return age;
    }
    public void m3(){
        System.out.println("TTT");
    }
}

//Fu m1方法

//10

//20

//TTT

//JJJ

左边类型决定了变量 能调用哪些方法,
右边类型决定了最终使用的方法是哪个 - 优先调用自己重写过的

口诀: 编译看左边, 运行看右边

1.2.1提前得知, 引用到底是什么类型的对象

上下转型,a1不进行强转,无法调用Cat类中的方法

package Demo1003;
//主类
public class Main {
    public static void main(String[] args) {
        //向上转型
        Animal a1 = new Cat();
        //向下转型
        Cat a3 = (Cat)a1;
        Animal a2 = new Dog();
        Dog a4 = (Dog)a2;
        a1.eat();
        a3.catchMouse();
        a2.eat();
        a4.watchHouse();
        getPet(a1);
        getPet(a2);
        salePet(a3);
        salePet(a4);
    }
    //输出变量
    public static Animal salePet(Animal t){
        if(t instanceof Cat){
            Cat n = (Cat)t;
            System.out.println("买" + n.name);
        }
        else if(t instanceof Dog){
            Dog n = (Dog)t;
            System.out.println("买" + n.name);
        }
        else{
            System.out.println();
        }
        return null;
    }
    //父类型作为返回值,功能扩展性更强,返回Animal类
    public static  void getPet(Animal n){
        //n instanceof Ob,判断n是否是Ob类型的对象
        if(n instanceof Cat){
            System.out.print("买了只猫");
            ((Cat) n).catchMouse();
            n.eat();
            Cat ab = (Cat)n;
            System.out.println(ab.name);
        }
        else if(n instanceof Dog){
            System.out.print("买了只狗");
            ((Dog) n).watchHouse();
            n.eat();
            Dog ab = (Dog)n;
            System.out.println(ab.name);
        }
    }

}


package Demo1003;
//父类
public abstract class Animal {
    public abstract void eat();
    String name = "宠物";
}


package Demo1003;
//Cat子类
public class Cat extends Animal{
    String name = "猫";
    public void catchMouse(){
        System.out.println("抓老鼠");
    }

    @Override
    public void eat() {
        System.out.println("猫吃猫粮");
    }
}


package Demo1003;
//Dog子类
public class Dog extends Animal{
    String name = "狗";
    public void watchHouse(){
        System.out.println("看家");
    }

    @Override
    public void eat() {
        System.out.println("狗吃狗粮");
    }
}
//猫吃猫粮

//抓老鼠

//狗吃狗粮

//看家

//买了只猫抓老鼠
//猫吃猫粮
//猫

//买了只狗看家
//狗吃狗粮
//狗

//买猫
//买狗

Animal -> abstract void eat()
Cat -> void catchMouse() {}
Dog -> void watchHouse() {}
多态: Animal a1 = new Cat();
Animal a2 = new Dog();
ClassCastException: 类型转换异常
解决方案: 转换之前先判断引用 实际上是不是要转换的类型对象
引用a instanceof 子类型 => boolean
问 a 实际上是不是子类型对象

1.3内部类:

1.3.1内部类示例

类中写个类
人体类 心脏类
车类 发动机类
种类: 成员内部类,静态内部类,局部内部类[匿名内部类]
成员内部类: 权限 public,protected,(default),private
语法:
public class Outer{
// …
public class Inner{
//…
}
}
使用:
内部类中, 可以随意使用外部类成员
外部类中, 使用内部类成员时需要创建内部类对象
无关类中, 使用内部类成员
1.间接调用, 在外部类方法中调用内部类方法
main方法中, 调用外部类方法
2.直接调用, 需要创建内部类对象
外部类.内部类 a = new 外部类().new 内部类();
内部类和外部类有同名成员变量
外部类的成员变量: 外部类.this.变量
内部类的成员变量: this.变量

package Demo1004;
//主类
public class Main {
    public static void main(String[] args) {
        //在无关类中使用Body内部的Heart
        Body body = new Body();
        System.out.println(body.a);
        //间接调用内部类,walk中有内部类
        body.walk();
        //直接调用内部类
        Body.Heart heart = body.new Heart();
        heart.beat();
        //调用内部变量
        System.out.println(heart.num);
        System.out.println(heart.a);
        //内部类中内部类的调用
        Body.Heart.Heart1 heart1 = heart.new Heart1();
        heart1.beat1();
    }
}


package Demo1004;

public class Body {
    int a = 10;
    //外部类的方法
    public void walk(){
        System.out.println("跑步");
        //外部类中直接创建内部对象
        Heart heart = new Heart();
        heart.beat();
        //外部类使用内部类变量不能直接调用,需要内部类对象
        System.out.println(heart.num);
    }
    //成员内部类:成分和外部类一样
    public class Heart{
        int num = 5;
        int a = 20;
        public void beat(){
            //如果内部类中没有定义a,内部类可以使用外部类的变量
            //System.out.println("心脏跳动" + a);
            //使用内部类的变量a
            System.out.println("心脏跳动" + a);
            //内部和外部的变量重名,内部类使用外部类的变量的方法
            System.out.println("心脏跳动" + Body.this.a);
            //内部类不能调用外部类,不然会无限循环
        }
        //在内部类中定义内部类
        public class Heart1{
            public void beat1(){
                System.out.println("心脏跳动更快了");
            }
        }
    }
}
//10

//跑步
//心脏跳动20
//心脏跳动10
//5

//心脏跳动20
//心脏跳动10

//5
//20

//心脏跳动更快了

1.3.2局部内部类:

在方法内部定义类, 只在方法中有效
在局部内部类中, 使用局部变量, 必须是final的
JDK8 后, 局部变量事实上没有发生改变, 那么final可以省略
一次性的类, 只能用一次
不能使用权限修饰符

局部内部类, 需要类只使用一次, 优化 -> 匿名内部类

package Demo1005;

public class Outer {
    int b = 20;
    public void m1(){
        int a = 10;
        //局部内部类不能使用权限修饰符
        class Inner{
            public void innerM1(){
                System.out.println("局部内部类M1" + a);
                System.out.println("成员变量b:"+ b);
            }
        }
        Inner i =new Inner();
        i.innerM1();
    }
    public void m2(){
        int a = 10;
        class Inner{

        }
    }

}



package Demo1005;

public class Main {
    public static void main(String[] args) {
        Outer out = new Outer();
        out.m1();

    }
}
//局部内部类M110
//成员变量b:20

1.3.3匿名内部类:

继承抽象类或实现接口
语法: new 接口/抽象类() {
int a;
// 实现的所有抽象方法
}
匿名内部类, 只能用一次, new一个对象
匿名对象, 只能使用一次, 只能调用一次方法
注意: 匿名内部类 和 匿名对象 不是一回事 ! ! !

package Demo1006;
//主类
public class Outer {
    public static void main(String[] args){
        //使用接口的方法
        //局部内部类
        InterFaceA impl = new InterFaceA() {
            @Override
            public void method() {
                System.out.println("内部类实现1");
            }

            @Override
            public void method01() {
                System.out.println("内部类实现2");
            }
        };
        impl.method();
        impl.method01();

        //匿名内部类
        InterFaceA impl1 = new InterFaceA()
        {
            @Override
            public void method() {
                System.out.println("内部实现类01");
            }
            @Override
            public void method01() {
                System.out.println("内部实现类02");
            }
        };

        impl1.method();
        impl1.method01();


    }

}



package Demo1006;
//实现类
public class InterImply implements InterFaceA{

    @Override
    public void method() {
    }

    @Override
    public void method01() {

    }
}


package Demo1006;
//接口类
public interface InterFaceA {
    void method();
    void method01();
}
//内部类实现1
//内部类实现2
//内部实现类01
//内部实现类02

静态内部类 对比 成员内部类 => 静态方法 和 成员方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值