• Java基础之接口与内部类


    接 口
     一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
    另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打
    印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
    接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是 "能不能"
    的关系。
     接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守
    接口的使用
    1.java 中使用interface来定义
    2.java 中接口和类是并列的关系
    3.如何定义接口,定义接口就是定义接口成员
    3.1 JDK7以前:只能定义 全局常量和抽象方法
    全局常量:pubic static final的;书写是可以省略
    抽象方法:pubic abstract的
    JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
    4接口不能定义构造器,也就是接口不能实例化
    5.java 开发中,接口通过让类实现(implements)的方式来使用
    如果实现类覆盖了接口中所有抽象方法,则此实现类可以实例化
    如果实现类没有覆盖接口中所有的抽象方法,则此实现类还是一个抽象类
    6.java 类可以实现多个接口---->弥补了类的单继承性
    格式 calss AA extends BB implement CC,DD{} ---->CC DD 是接口
    7.接口与接口之间可以继承而且可以多继承



    示例
    public class InterfaceTest {
        public static void main(String[] args) {
            System.out.println(Flyale.MIN_SPEED);
            System.out.println(Flyale.MAX_SPEED);
            plane p1 = new plane();
            p1.fly();
            plane p2 = new plane();
            p2.fly();
            kite k1 = new kite();
            k1.fly();
            k1.stop();
        }
    
    }
    //接口的定义
    interface  Flyale{
        //全局常量
        public static final int MAX_SPEED = 7900;//第一宇宙速度
        public  static  final int MIN_SPEED =1;//在接口可以写成int MIN_SPEED =1
        //抽象方法
        public abstract  void fly();//在接口定义的方法也可以这样写void fly();
        //可以省略public abstract
        public abstract void  stop();//在接口定义的方法也可以这样写void stop()
    
    }
    class  plane implements  Flyale{
        @Override
        public void fly(){
            System.out.println("通过引擎");
    
        }
        @Override
        public void stop(){
            System.out.println("通过关闭引擎");
        }
    }
    class  kite implements  Flyale{
        @Override
        public void fly(){
            System.out.println("依靠风");
        }
    
        @Override
        public void stop() {
            System.out.println("收好风筝线");
    
        }
    }
    

      测试结果

    1
    7900
    通过引擎
    通过引擎
    依靠风
    收好风筝线
    

      示例2

    public class InterfaceTest {
        public static void main(String[] args) {
            System.out.println(Flyale.MIN_SPEED);
            System.out.println(Flyale.MAX_SPEED);
            plane p1 = new plane();
            p1.fly();
            plane p2 = new plane();
            p2.fly();
            kite k1 = new kite();
            k1.fly();
            k1.stop();
        }
    
    }
    //接口的定义
    interface  Attackable{
        void attackble();//接口里定义方法
    }
    interface  Flyale{
        //全局常量
        public static final int MAX_SPEED = 7900;//第一宇宙速度
        public  static  final int MIN_SPEED =1;//在接口可以写成int MIN_SPEED =1
        //抽象方法
        public abstract  void fly();//在接口定义的方法也可以这样写void fly();
        //可以省略public abstract
        public abstract void  stop();//在接口定义的方法也可以这样写void stop()
    
    }
    class  plane implements  Flyale{
        @Override
        public void fly(){
            System.out.println("通过引擎");
    
        }
        @Override
        public void stop(){
            System.out.println("通过关闭引擎");
        }
    }
    class  kite implements  Flyale{
        @Override
        public void fly(){
            System.out.println("依靠风");
        }
    
        @Override
        public void stop() {
            System.out.println("收好风筝线");
    
        }
    
    }
    class Bullet  implements Flyale,Attackable{ //一个类可以有多个接口中间使用逗号隔开
    
        @Override
        public void fly(){
    
        }
        @Override
        public void  stop(){
    
        }
        @Override
        public void attackble(){
    
        }
    
    }
    interface AA{
    
    }
    interface BB{
    
    }
    interface  CC extends AA,BB{ //接口可以定义多个继承的接口,中间使用,号隔开
    
    }
    

      Java 8 的心特性

    Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
    静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中
    找到像Collection/Collections或者Path/Paths这样成对的接口和类。
    默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
    比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法
    JAVA 8的新特性,除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
    定义的静态方法只能通过接口去调
    定义的默认方法可以通过对象调
    接口定义示例
    public interface CompareA {
        //静态方法
            public static void method1(){
                System.out.println("北京");
            }
            //默认方法
            public default void method2(){
                System.out.println("上海");
            }
            //默认方法
            default void  method3(){
                System.out.println("深圳");
            }
    }
    

      测试

    public class SubClassTese {
        public static void main(String[] args) {
            SubClass s1 = new SubClass();
            //接口定义的静态方法只能通过接口来调用
            CompareA.method1();
            //默认方法通过对象调
            s1.method2();
        }
    
    }
    class SubClass implements  CompareA{
    
    }
    
    
    
    测试结果
    北京
    上海
    

      重写方法

    测试

    package com.chenxi.Java8;
    
    public class SubClassTese {
        public static void main(String[] args) {
            SubClass s1 = new SubClass();
            //接口定义的静态方法只能通过接口来调用
            CompareA.method1();
            //默认方法通过对象调;如果重写接口方法就是调的重写后的方法
            s1.method2();
        }
    
    }
    class SubClass implements  CompareA{
        @Override
        public void method2() {
            System.out.println("杭州");
        }
    }
    
    
    测试
    北京
    杭州
    

      如果子类或实现类声明了同名同参的方法,在子类没有重写此方法的情况下;默认去去调父类的方法

      如果实现类实现了多个接口,而多个接口有同名同参的默认方法,那么在实现类没有重写此方法的情况下,报错

    接口

    public interface CompareA {
        //静态方法
            public static void method1(){
                System.out.println("北京");
            }
            //默认方法
            public default void method2(){
                System.out.println("上海");
            }
            //默认方法
            default void  method3(){
                System.out.println("深圳");
            }
    }
    

      父类

    public class SuperClass {
        public void method3(){
            System.out.println("云南");
        }
    }
    

      测试

    public class SubClassTese {
        public static void main(String[] args) {
            SubClass s1 = new SubClass();
            //接口定义的静态方法只能通过接口来调用
            CompareA.method1();
            //默认方法通过对象调
            s1.method2();
            //如果子类或实现类声明了同名同参的方法,子类没有重写此方法的情况下;默认去调父类的方法
            s1.method3();//
        }
    
    }
    class SubClass extends SuperClass implements  CompareA{
        @Override
        public void method2() {
            System.out.println("杭州");
        }
    
    }
    测试
    北京
    杭州
    云南
    

      内部类

    当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。
    在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者、称为外部类。
     Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
    Inner class的名字不能与包含它的外部类类名相同;
    分类: 成员内部类(static成员内部类和非static成员内部类)局部内部类(不谈修饰符)、匿名内部类
    类的内部类
    1.java 允许将一个类A声明在另一个类B中,则A类是内部类,类B外部类
    2. 内部类的分类 :成员内部类(静态、非静态)VS 局部内部类(方法内、代码块内、构造器内)
    3.成员内部类
    作为外部类的成员
    调用外部类的属性
    可以被4中权限修饰
    可以被static 修饰
    作为类内部类可以定义属性、方法构造器等
    final 修饰 表示不可以被继承
    可以被abstract 修饰
    关注如下3个问题
    如何实例化内部类的对象
    如何在成员类中区分调用外部类的结果
    局部内类的使用
    实例
    public class InnerClassTest{
        public static void main(String[] args) {
            //创建Dog 实例(静态的成员内部类)
            Person.Dog dog = new Person.Dog();
            dog.show();
            //创建Bird实例(非静态的成员内部类)
            Person p = new Person();
            Person.Bird bird = p.new Bird();
            bird.sing();
    
    
        }
    
    }
    class Person{
        String name;
        public Person(){
            //构造器里声明的局部内部类
            class  es{
    
            }
        }
        public void eat(){
            System.out.println("人吃饭");
        }
        //成员内部类:非静态的成员内部类
        class Bird{
    
            String name="杜鹃";
            public Bird(){
    
            }
            public  void sing(){
                System.out.println("我是一只小小鸟");
                Person.this.eat();//调用外部类的结构
            }
            public void display(String name){
                System.out.println(name);//方法形参
                System.out.println(this.name);//内部类的属性
                System.out.println(Person.this.name);//外部类的属性
            }
    
        }
    

      局部内部类的使用

    public class InnerClassTest1 {
        public void method(){
            class AA{
    
            }
        }
        public Comparable getComparable(){
    
            //创建一个实现Comparable接口的类:局部内部类
                //方式1
    //        class  MyComparable implements Comparable{
    //            @Override
    //            public int compareTo(Object o) {
    //                return 0;
    //            }
    //        }
    //        return new MyComparable();
            //方式2匿名类的匿名对象
            return new Comparable() {
                @Override
                public int compareTo(Object o) {
                    return 0;
                }
            };
        }
     }
    

      



    草都可以从石头缝隙中长出来更可况你呢
  • 相关阅读:
    Qt状态机实例
    <STL> accumulate 与 自定义数据类型
    <STL> 容器混合使用
    散列表(C版)
    Canonical 要将 Qt 应用带入 Ubuntu
    <STL> set随笔
    C++ 文件流
    视频播放的基本原理
    <STL> pair随笔
    c++ 内存存储 解决char*p, char p[]的问题
  • 原文地址:https://www.cnblogs.com/rdchenxi/p/14643154.html
Copyright © 2020-2023  润新知