美文网首页一些收藏
Java-接口与抽象类

Java-接口与抽象类

作者: Cool_Pomelo | 来源:发表于2020-01-15 09:31 被阅读0次

    Java-接口与抽象类

    抽象类

    如果编写一个类时,我们只想为该类定义一些方法,但是具体的实现交给继承它的子类来实现的话,我们可以考虑使用抽象类

    抽象方法与抽象类

    抽象方法与抽象类都必须使用abstract来修饰

    • 有抽象方法的类只能被定义为抽象类

    • 抽象类里面可以没有抽象方法

    规则:

    • 抽象方法与抽象类都必须使用abstract来修饰,抽象方法不能有方法体

    • 抽象类不能实例化

    • 抽象类可以包含成员变量,方法(普通或者抽象方法都可以),构造函数,初始化块,内部类5种成分

    • 含有抽象方法的类只能被定义为抽象类

    public abstract class Shape {
    
        {
            System.out.println("执行Shape的初始化块...");
        }
        private String color;
        // 定义一个计算周长的抽象方法
        public abstract double calPerimeter();
        // 定义一个返回形状的抽象方法
        public abstract String getType();
        // 定义Shape的构造器,该构造器并不是用于创建Shape对象,
        // 而是用于被子类调用
        public Shape(){}
        public Shape(String color)
        {
            System.out.println("执行Shape的构造器...");
            this.color = color;
        }
        // 省略color的setter和getter方法
        public void setColor(String color)
        {
            this.color = color;
        }
        public String getColor()
        {
            return this.color;
        }
    }
    
    public class Triangle extends Shape{
    
        // 定义三角形的三边
        private double a;
        private double b;
        private double c;
        public Triangle(String color , double a
                , double b , double c)
        {
            super(color);
            this.setSides(a , b , c);
        }
        public void setSides(double a , double b , double c)
        {
            if (a >= b + c || b >= a + c || c >= a + b)
            {
                System.out.println("三角形两边之和必须大于第三边");
                return;
            }
            this.a = a;
            this.b = b;
            this.c = c;
        }
        // 重写Shape类的的计算周长的抽象方法
        public double calPerimeter()
        {
            return a + b + c;
        }
        // 重写Shape类的的返回形状的抽象方法
        public String getType()
        {
            return "三角形";
        }
    
    
    }
    
    public class Circle extends Shape{
    
        private double radius;
        public Circle(String color , double radius)
        {
            super(color);
            this.radius = radius;
        }
        public void setRadius(double radius)
        {
            this.radius = radius;
        }
        // 重写Shape类的的计算周长的抽象方法
        public double calPerimeter()
        {
            return 2 * Math.PI * radius;
        }
        // 重写Shape类的的返回形状的抽象方法
        public String getType()
        {
            return getColor() + "圆形";
        }
        public static void main(String[] args)
        {
            Shape s1 = new Triangle("黑色" , 3 , 4, 5);
            Shape s2 = new Circle("黄色" , 3);
            System.out.println(s1.getType());
            System.out.println(s1.calPerimeter());
            System.out.println(s2.getType());
            System.out.println(s2.calPerimeter());
        }
    }
    
    

    注意:

    • static和abstract不能同时修饰某个方法

    • priva和abstract不能同时修饰方法

    接口

    抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更加彻底,那么就可以引出接口了

    接口概念

    接口是从多个相似类中抽象出来的规范,接口不提供任何实现,接口体现的是规范和实现分离的设计哲学

    接口定义的基本语法:

    [修饰符] interface 接口名 extends 父接口1,父接口2...
    {
            0-n个常量定义...
            0-n个抽象方法定义...
            0-n个内部类、接口、枚举定义...
            0-n个私有方法、默认方法、类方法定义...
    }
    
    
    • 修饰符可以是public或者省略,省略的话默认采用包权限访问控制符

    • 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类

    接口中不能包含构造函数以及初始化块定义,可以包含成员变量(只能是静态常量),方法(只能是抽象实例方法、类方法、默认方法、私有方法),内部类(内部接口、枚举)定义

    接口里面的常量、方法、内部类、内部枚举都是public访问权限,定义时可以省略访问控制修饰符,如果指定的话只能用public

    接口里定义的静态常量系统会自动为这些变量增加static和final修饰符

    接口里定义的成员变量只能在定义时指定默认值

    接口里面如果不是定义默认方法、类方法、私有方法,系统自动为普通方法添加abstract修饰符,接口里面普通方法不能有方法实现;但是类方法、默认方法、私有方法都必须有方法实现

    定义一个接口:

    public interface Output {
    
    
        // 接口里定义的成员变量只能是常量
        int MAX_CACHE_LINE = 50;
        // 接口里定义的普通方法只能是public的抽象方法
        void out();
        void getData(String msg);
        // 在接口中定义默认方法,需要使用default修饰
        default void print(String... msgs)
        {
            for (String msg : msgs)
            {
                System.out.println(msg);
            }
        }
        // 在接口中定义默认方法,需要使用default修饰
        default void test()
        {
            System.out.println("默认的test()方法");
        }
        // 在接口中定义类方法,需要使用static修饰
        static String staticTest()
        {
            return "接口里的类方法";
        }
    
    
    //    // 定义私有方法(要java9及其以上才可以)
    //    private void foo()
    //    {
    //        System.out.println("foo私有方法");
    //    }
    //    // 定义私有静态方法
    //    private static void bar()
    //    {
    //        System.out.println("bar私有静态方法");
    //    }
    }
    

    接口的继承

    接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个之间父接口,和类继承相似,子接口扩展某个父接口将会获得父接口里面定义的所有抽象方法,常量

    一个接口继承多个父接口时,多个父接口排在extends关键字后面

    interface InterfaceA
    {
        int PROP_A = 5;
        void testA();
    }
    interface InterfaceB
    {
        int PROP_B = 6;
        void testB();
    }
    interface InterfaceC extends InterfaceA, InterfaceB
    {
        int PROP_C = 7;
        void testC();
    }
    public class InterfaceExtendsTest
    {
        public static void main(String[] args)
        {
            System.out.println(InterfaceC.PROP_A);
            System.out.println(InterfaceC.PROP_B);
            System.out.println(InterfaceC.PROP_C);
        }
    }
    
    
    

    使用接口

    接口不能用于创建实例,但是接口可以用于声明引用类型变量,此时这个引用类型变量必须引用到其实现类的对象

    类实现接口语法:

    [修饰符] class 类名 extends 父类 implement 接口1,接口2...
    
    

    implement部分必须放置在extends后面

    一个类实现了接口后,必须完全实现这些接口里面所定义的全部抽象方法,否则该类必须定义为抽象类

    
    // 定义一个Product接口
    interface Product
    {
        int getProduceTime();
    }
    // 让Printer类实现Output和Product接口
    public class Printer implements Output , Product
    {
        private String[] printData
                = new String[MAX_CACHE_LINE];
        // 用以记录当前需打印的作业数
        private int dataNum = 0;
        public void out()
        {
            // 只要还有作业,继续打印
            while(dataNum > 0)
            {
                System.out.println("打印机打印:" + printData[0]);
                // 把作业队列整体前移一位,并将剩下的作业数减1
                System.arraycopy(printData , 1
                        , printData, 0, --dataNum);
            }
        }
        public void getData(String msg)
        {
            if (dataNum >= MAX_CACHE_LINE)
            {
                System.out.println("输出队列已满,添加失败");
            }
            else
            {
                // 把打印数据添加到队列里,已保存数据的数量加1。
                printData[dataNum++] = msg;
            }
        }
        public int getProduceTime()
        {
            return 45;
        }
        public static void main(String[] args)
        {
            // 创建一个Printer对象,当成Output使用
            Output o = new Printer();
            o.getData("hello");
            o.getData("world");
            o.out();
            o.getData("test");
            o.getData("case");
            o.out();
            // 调用Output接口中定义的默认方法
            o.print("孙悟空" , "猪八戒" , "白骨精");
            o.test();
            // 创建一个Printer对象,当成Product使用
            Product p = new Printer();
            System.out.println(p.getProduceTime());
            // 所有接口类型的引用变量都可直接赋给Object类型的变量
            Object obj = p;
        }
    }
    

    实现接口方法时,必须使用public修饰符

    接口与抽象类之间的区别:

    • 接口只能有抽象方法、静态方法、默认方法、私有方法,不可以为普通方法提供实现;抽象类完全可以包含普通方法

    • 接口里只可以定义静态常量,不准出现普通成员变量;抽象类可以定义普通成员变量以及静态常量

    • 接口无构造函数,抽象可可以有

    • 接口里不包含初始化块,抽象类可以包含

    • 一个类最多有一个直接父类,包括抽象类,一个类可以实现多个接口

    相关文章

      网友评论

        本文标题:Java-接口与抽象类

        本文链接:https://www.haomeiwen.com/subject/qcazactx.html