zoukankan      html  css  js  c++  java
  • 接口

    JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如“金丝猴是一种动物”,金丝猴从动物这个类继承,同时“金丝猴是一种值钱的东西”,金丝猴从“值钱的东西”这个类继承,同时“金丝猴是一种应该受到保护的东西”,金丝猴从“应该受到保护的东西”这个类继承。这样金丝猴可以同时从 “动物类”、“值钱的东西类”、“应该受到保护的东西” 这三个类继承,但由于JAVA只支持单继承,因此金丝猴只能从这三个类中的一个来继承,不能同时继承这三个类。因此为了封装现实生活中存在的多重继承现象,为了实现多继承,可以把其中的两个类封装成接口。使用接口可以帮助我们实现多重继承。

    接口的本质——接口是一种特殊的抽象类,这种抽象类里面只包含常量和方法的定义,而没有变量和方法的实现。

      抽象类所具有的一些东西接口可以具有,假如一个抽象类里面所有的方法全都是抽象的,没有任何一个方法需要这个抽象类去实现,并且这个抽象类里面所有的变量都是静态(static)变量,都是不能改变(final)的变量,这时可以把这样的抽象类定义为一个接口(interface)把一个类定义成一个接口的格式是把声明类的关键字class用声明接口的关键字interface替换掉即可。

    作为接口来说,一个类可以从接口继承(或者叫实现接口),这也是多继承,接口里面的成员变量不专属于某个对象,都是静态的成员变量,是属于整个类的,因此一个类去实现多个接口也是无所谓的,不会存在对象之间互相冲突的问题。实现多个接口,也就实现了多重继承,而且又避免了多重继承容易出现问题的地方,这就是用接口实现多重继承的好处。

    举例:

    package javastudy.summary;
    
    /**
     * 这里定义了接口:Painter。 在Painter接口里面定义了paint()和eat()这两个抽象方法。
     * 
     * @author gacl
     * 
     */
    interface Painter {
        public void eat();
    
        public void paint();
    }
    
    /**
     * 这里定义了两个接口:Singer 在Singer接口里面定义了sing()和sleep()这两个抽象方法。
     * 
     * @author gacl
     * 
     */
    interface Singer {
        public void sing();
    
        public void sleep();
    }
    
    /**
     * 类Student实现了Singer这个接口
     * 
     * @author gacl
     * 
     */
    class Student implements Singer {
    
        private String name;
    
        public Student(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        /**
         * 实现接口中定义的sing方法
         */
        @Override
        public void sing() {
            System.out.println("student is singing");
        }
    
        /**
         * 实现接口中定义的sleep方法
         */
        @Override
        public void sleep() {
            System.out.println("student is sleeping");
        }
    
        public void study() {
            System.out.println("Studying...");
        }
    
    }
    
    /**
     * Teacher这个类实现了两个接口:Singer和Painter。 这里Teacher这个类通过实现两个不相关的接口而实现了多重继承。
     * 
     * @author gacl
     * 
     */
    class Teacher implements Singer, Painter {
    
        private String name;
    
        public Teacher(String name) {
            this.name = name;
        }
    
        /**
         * 在Teacher类里面重写了这两个接口里面的抽象方法,
         * 通过重写抽象方法实现了这两个接口里面的抽象方法。
         */
        @Override
        public void eat() {
            System.out.println("teacher is eating");
        }
    
        public String getName() {
            return name;
        }
    
        @Override
        public void paint() {
            System.out.println("teacher is painting");
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void sing() {
            System.out.println("teacher is singing");
        }
    
        @Override
        public void sleep() {
            System.out.println("teacher is sleeping");
        }
    
        public void teach() {
            System.out.println("teaching...");
        }
    }
    
    public class TestInterfaces {
    
        public static void main(String[] args) {
            /**
             * 这里定义了一个接口类型的变量s1
             */
            Singer s1 = new Student("le");
            s1.sing();
            s1.sleep();
            Singer s2 = new Teacher("steven");
            s2.sing();
            s2.sleep();
            Painter p1 = (Painter)s2;
            p1.paint();
            p1.eat();
        }
    }

    运行结果:

    这里验证了两个规则,“一个类可以实现多个无关的接口”,Teacher类既实现了Singer接口,同时也实现了Painter接口,而Singer接口和Painter接口是无关系的两个接口。“多个无关的类可以实现同一接口”,Student类和Teacher类都实现了Singer接口,而Student类和Teacher类并不是关系很密切的两个类,可以说是无关的两个类。

     举例2:

    package javastudy.summary;
    
    /**
     * 把“值钱的东西”这个类定义成一个接口Valuable。在接口里面定义了一个抽象方法getMoney()
     * @author gacl
     *
     */
    interface Valuable {
        public double getMoney();
    }
    
    /**
     * 把“应该受到保护的东西”这个类定义成一个接口Protectable。
     * 在接口里面定义了一个抽象方法beProtected();
     * @author gacl
     *
     */
    interface Protectable {
        public void beProteced();
    }
    
    /**
     * 这里是接口与接口之间的继承,接口A继承了接口Protectable,
     * 因此自然而然地继承了接口Protectable里面的抽象方法beProtected()。
     * 因此某一类去实现接口A时,除了要实现接口A里面定义的抽象方法m()以外,
     * 还要实现接口A从它的父接口继承下来的抽象方法beProtected()。
     * 只有把这两个抽象方法都实现了才算是实现了接口A。
     * @author gacl
     *
     */
    interface A extends Protectable {
        void m();
    }
    
    /**
     * 这里定义了一个抽象类Animal。
     * @author gacl
     *
     */
    abstract class Animal {
        private String name;
        /**
         * 在Animal类里面声明了一个抽象方法enjoy()
         */
        abstract void enjoy();
    }
    
    /**
     * 这里是为了实现了我们原来的语义:
     * “金丝猴是一种动物”同时“他也是一种值钱的东西”同时“他也是应该受到保护的东西”。而定义的一个类GoldenMonKey。
     * 为了实现上面的语义,这里把“值钱的东西”这个类定义成了一个接口Valuable,
     * 把“应该受到保护的东西”这个类也定义成了一个接口Protectable。这样就可以实现多继承了。
     * GoldenMonKey类首先从Animal类继承,然后GoldenMonKey类再去实现Valuable接口和Protectable接口,
     * 这样就可以实现GoldenMonKey类同时从Animal类,Valuable类,Protectable类继承了,即实现了多重继承,
     * 实现了原来的语义。
     * @author gacl
     *
     */
    class GoldenMonKey extends Animal implements Valuable,Protectable {
    
        /**
         * 在GoldenMoKey类里面重写了接口Protectable里面的beProtected()这个抽象方法,
         * 实现了接口Protectable。
         */
        @Override
        public void beProteced() {
            System.out.println("live in the Room");
        }
    
        /**
         * 在GoldenMoKey类里面重写了接口Valuable里面的getMoney()这个抽象方法,实现了接口Valuable。
         */
        @Override
        public double getMoney() {
            return 10000;
        }
    
        /**
         * 这里重写了从抽象类Animal继承下来的抽象方法enjoy()。
         * 实现了这抽象方法,不过这里是空实现,空实现也是一种实现。
         */
        @Override
        void enjoy() {
            
        }
        
        public static void test() {
            /**
             * 实际当中在内存里面我们new的是金丝猴,在金丝猴里面有很多的方法,
             * 但是接口的引用对象v能看到的就只有在接口Valuable里面声明的getMoney()方法,
             * 因此可以使用v.getMoney()来调用方法。而别的方法v都看不到,自然也调用不到了。
             */
            Valuable v = new GoldenMonKey();
            System.out.println(v.getMoney());
            /**
             * 把v强制转换成p,相当于换了一个窗口,通过这个窗口只能看得到接口Protectable里面的beProtected()方法
             */
            Protectable p = (Protectable)v;
            p.beProteced();
        } 
    }
    
    /**
     * 这里让Hen类去实现接口A,接口A又是从接口Protectable继承而来,接口A自己又定义了一个抽象方法m(),
     * 所以此时相当于接口A里面有两个抽象方法:m()和beProtected()。
     * 因此Hen类要去实现接口A,就要重写A里面的两个抽象方法,实现了这两个抽象方法后才算是实现了接口A。
     * @author gacl
     *
     */
    class Hen implements A {
    
        @Override
        public void beProteced() {
            
        }
    
        @Override
        public void m() {
            
        }
        
    }
    
    /**
     * java中定义接口
     */
    public class JavaInterfacesTest {
    
        public static void main(String[] args) {
            GoldenMonKey.test();
        }
    }
  • 相关阅读:
    aliyun添加swap虚拟内存。
    mysql 的备份与恢复。转载。
    springmvc 集成 ckeditor,附带图片上传功能。
    转载 tomcat linux 下, tomcat假死的解决办法,另:manager开启,在centos7巨慢问题,war部署在根目录
    springmvc 在前端jsp页面,select标签显示复合条件。和 session跨页面操作。
    复杂的联合查询,mybatis的例子。
    springmvc CRUD控制器写法和jsp页面写法 总结大全。
    springmvc,在更新页面,输入时报丢失参数, Missing URI template variable 'id ' for method parameter of type Integer
    springmvc select 标签的默认选中,和springmvc控制器 错误回显时,带值。
    在linux centos7 上安装java运行时环境,tomcat自启动脚本
  • 原文地址:https://www.cnblogs.com/qq1312583369/p/10958309.html
Copyright © 2011-2022 走看看