首页 > 技术文章 > java 抽象类 接口

shangjinshuai 2020-11-24 19:04 原文

抽象类
    概述
        父类中的方法,被他们的子类们重写,子类的各自实现又不一样.那么父类的方法声明和方法体,
            只有声明才有意义,而方法体的内容则没有存在的意义.我们把这种没有方法体内容的方法,称为抽象方法
            java语法规定,如果一个类包含了抽象方法.那么该类就是一个抽象类
    
    定义:
        抽象方法:没有方法体的方法就是抽象方法
        抽象类:包含抽象方法的类
        
    abstract关键字使用格式
        抽象方法
            使用abstract关键字修饰成员方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体
            
        定义格式:
            修饰符 abstract 返回值类型 方法名(参数列表);
            示例代码:
                public abstract void run();
                //吃饭的的抽象方法
                public abstract void eat();
                //动物跳跃的抽象方法
                public abstract void jump();
    抽象类:
        定义格式:
            修饰符 abstract class ClassName{}
            示例代码:
                public abstract class Adimal{
                    //奔跑的抽象方法
                    public abstract void run();
                }
                
                public abstract class People{
                    //吃饭的抽象方法
                    public abstract void eat();
                }
                
    抽象的使用
        继承抽象类的子类必须重写父类的所有的抽象方法.否则,该子类也必须声明为一个抽象类.
        
    注意事项
        关于抽象类的使用,需要注意的事项
            1.抽象类不能创建对象,如果创建对象,编译无法通过.只能创建其非抽象子类的对象
            2.抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的.
            3.抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象的
            4.抽象类的子类,必须重写父类中的所有抽象方法,否则编译无法通过,除非该子类也是抽象类.
            
            
            
            
            
接口:
    学习目标:
        1.能够写出定义接口的格式
        2.能够写出实现接口的格式
        3.能够说出接口中成员+的特点
        4.能够说出多态的前提条件
        5.能够理解多态的向上转型
        6.理解多态的向下转型
        7.能够使用多态和接口完成相应的案例开发
        
    概述:
        接口:是java语言中的引用类型,是方法的集合,如果说类的内部封装了成员变量,构造方法,成员方法,
            那么接口的内部主要就是【封装了方法】,包含了抽象方法、(JDK1.7及以前)默认的方法和静态的方法(JDK1.8)
            私有方法(JDK1.9)
        接口的定义:他与类的定义很相似,但是使用的interface关键字,他也会被编译生成为class文件,
            但一定要明确他并不是类,而是另外一种引用数据类型
            
            引用数据类型:类、数组、接口
            
        接口的使用,不能直接创建对象,但是可以被实现(implements关键字,类似于被继承但又不是)一个实现接口的类
            (可以看做是接口的子类),需要重写接口当中的所有抽象方法,创建该类对象,就可以调用方法了.
        接口的定义格式
            public interface 接口名称{
                //抽象方法 以抽象方法为主
                //默认方法
                //常量
                //静态方法
                //私有方法(JDK1.9)
            }
            含有抽象方法
                抽象方法:使用abstract关键字修饰,没有方法体内容,该方法主要是供子类使用的
                public interface InterfaceName{
                    public abstract void method();
                    //在接口中 public abstract 可以省略不写
                }
            含有默认方法和静态方法
                默认方法: 使用【default】关键字修饰的方法,不可省略,供子类调用或者子类重写.
                静态方法: 使用的是【static】关键字修饰的方法.供接口直接调用
                
            含有私有方法和私有的静态方法
                私有方法:使用private关键字,供接口中的默认方法或者是静态方法调用
                代码如下:
                    public interface InterfaceName{
                        private void method(){
                            //方法体内容
                        }
                    }
        
        基本的实现
            实现的概述
                类与接口的关系为实现关系,即类实现接口,该类可以成为接口的实现类,也可以称为接口的子类.
                    实现的动作类似于继承,格式相仿,只是关键字不同,实现使用【implements】关键字
                    
            非抽象类实现接口:
                1.必须重写接口当中所有的抽象方法
                2.继承了接口当中的默认方法即可以直接调用,也可以重写
            实现格式:
                public class 实现类 implements 接口名称{
                    //重写接口当中的所有抽象方法
                    //重写接口当中的默认方法【可选】
                }
            抽象方法的使用:
                必须全部实现:
                代码如下:
                    定义一个接口:
                        public interface Biological{//生物
                            //定义一个吃东西的功能
                            public abstract void eat();
                            //定义一个休息的功能
                            public abstract void sleep();
                            
                        }
                        //定义一个实现类
                        public class Animal implements Biological{
                            @Override
                            public void eat(){
                                System.out.println("吃东西");
                            }
                            @Override
                            public void sleep(){
                                System.out.println("睡觉");
                            }
                        }
                        //定义测试类
                        public class InterfaceDemo01{
                            public static void main(String[] args){
                                //创建子类对象
                                Adimal adimal = new Adimal();
                                //调用重写之后的方法
                                adimal.eat();
                                adimal.sleep();
                            }
                        }
                        //输出结果
                        //吃东西
                        //睡觉
                        
            默认方法的使用
                可以继承,可以重写,二选一但是只能通过实现类的对象来调用
                    1.继承默认方法,代码如下
                    public interface Biological{//生物
                        //定义一个飞的功能
                        public default void fly();
                        System.out.println("天上飞");
                        
                    }
                    //定义实现类
                    public class Adimal implements Biological{
                        //继承 什么都不写 直接调用
                    }
                    //定义测试类:
                    public class InterfaceDemo02 {
                        public static void main (String[] args){
                            //创建子类对象
                            Adimal ani = new Adimal();
                            //调用默认方法
                            ani.fly();
                        }
                        
                    }
                    //输出结果:
                    //天上飞
                    
                    2.重写默认方法,代码如下
                    public interface Biological{//生物
                        //定义一个飞的功能
                        public default void fly();
                        System.out.println("天上飞");
                        
                    }
                    //定义实现类
                    public class Adimal implements Biological{
                        //重写
                        @Override
                        public void fly(){
                            System.out.println("自由自在的飞");
                        }
                    }
                    //定义测试类:
                    public class InterfaceDemo03 {
                        public static void main (String[] args){
                            //创建子类对象
                            Adimal ani = new Adimal();
                            //调用默认方法
                            ani.fly();
                        }
                        
                    }
                    //输出结果:
                    //自由自在的飞
                    
                    3.静态方法的使用
                    静态的一般都是和类.class文件相关,【只能】使用接口名来调用,
                        不可以通过实现类的类名或者是实现类的对象来调用
                    代码如下:
                    public interface Biological{//生物
                        //定义一个飞的功能
                        public static void run(){
                            System.out.println("跑起来吧");
                        }                        
                    }
                    //定义实现类
                    public class Adimal implements Biological{
                        //无法重写静态方法
                        
                    }
                    //定义测试类:
                    public class InterfaceDemo04 {
                        public static void main (String[] args){

                            Animal.run();//错误操作,无法继承,也无法调用
                            //调用静态方法
                            Biological.run();
                        }
                        
                    }
                    //输出结果:
                    //跑起来吧

                    4.私有方法的使用
                        私有方法:只有默认方法可以调用
                        私有静态方法:默认方法和静态方法都可以调用
                        
                        如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中
                            供默认方法去调用.从设计角度考虑,私有的方法是对默认的方法和静态的方法的一种辅助.
                        
                        代码如下:
                            //定义一个接口
                            public interface Biological{//生物
                                
                                private void run1(){
                                    System.out.println("跑起来....");
                                }
                                
                                public default void funMethod1(){
                                    //System.out.println("跑起来...");
                                    run1();
                                }
                                
                                public default void funMethod2(){
                                    //System.out.println("跑起来...");
                                    run1();
                                }            
                            }
    
                    
        接口的多实现
            在继承体系中,一个类只能直接继承一个父类,而对于接口来说,一个类可以实现多个接口,这叫做接口的【多实现】
                并且一个类能直接继承一个父类,同时还可以实现 多个接口
            实现格式:
                public class ClassName extends 父类 implements 接口名1,接口2,......{
                    //重写接口中的所有抽象方法
                    //重写接口中的默认方法【可选】
                    //抽象方法重名
                    
                }
            抽象方法:
                接口中,有多个抽象方法,实现类必须重写所有的抽象方法,如果抽象方法名有重名,之需要重写一次即可
                代码如下:
                //定义多个接口
                public interface Adimal{
                    public abstract void eat();
                    public abstract void run();
                }
                public interface Human{
                    public abstract void eat();
                    public abstract void run();
                }
                //定义实现类
                public class People implements Adimal,Human{
                    @Override
                    public void eat(){
                        System.out.println("吃东西!");
                    }
                    public abstract void run(){
                        System.out.println("健身");
                    }
                }
            默认方法
                接口中,有多个默认方法是,实现类都可继承使用,如果默认方法有重名的,【必须重写一次】
                代码如下:
                public interface A{
                    public default void methodA(){}
                    public default void method(){}
                }
                public interface B{
                    public default void methodB(){}
                    public default void method(){}
                }
                //定义实现类
                public class C implements A,B{
                    @Override
                    public void method(){
                        System.out.println("method方法被重写...")
                    }
                }
            静态方法:
                接口中,如果存在同名的静态方法并不会冲突,原因只能通过各自的接口名来访问静态方法.
                
            优先级问题
                当一个类,既继承了一个父类又同时实现了多个接口,父类当中的成员方法与接口当中的默认方法重名
                    【子类就近选择执行父类的成员方法】
                代码如下:
                    public interface A{
                        public default void methodA{
                            System.out.println("AAAAA");
                        }
                    }
                    //定义父类
                    public class D{
                        public void methodA(){
                            System.out.println("dddddd");
                        }
                    }
                    //定义子类
                    public class E extends D implements A{
                        //未重写methodA()方法
                    }
                    //定义测试类
                    public class TestInterfaceDemo06{
                        public static void main(String[] args){
                            //创建子类对象E
                            E e = new E();
                            e.methodA();
                        }
                    }
            接口的多继承【了解】
                一个接口能继承另一个接口或者多个接口,这和类之间的继承比较相似 接口的继承使用extends关键字
                    子接口继承父接口的方法,如果父接口中的默认方法有重名方法,那么子接口需要重写一次.
                    
                public interface A{
                    public default void method(){
                        System.out.println("aaaaaaaaaaa");
                    }
                }
                public interface B{
                    public default void method(){
                        System.out.println("bbbbbbbbbbbb");
                    }
                }
                //定义子接口
                public interface C extends A,B{
                    @Override
                    public default void method(){
                        System.out.println("ccccccc")
                    }
                }
                备注:子接口重写默认方法,default关键字不能省 保留
                
            其他成员特点
                接口中,无法定义成员变量,但是可以定义常量,因为值不可变,默认使用public static final 修饰的
                接口中,没有构造方法,不能创建对象
                接口当中,没有静态代码块
                
            接口的好处
                1.接口可以(设定)定义规则
                2.降低耦合性 【高内聚 低耦合】
                3.可以扩展原有类的功能
                
            接口与抽象类的区别:
                相同点:
                    都包含抽象方法,其子类都必须重写这些抽象方法
                    都不能直接实例化对象
                    都位于继承的顶端(当父类)用于被其它类实现或者继承
                区别:
                    抽象类里面可以包含普通成员方法 接口不能包含普通成员方法
                    一个类只能直接继承一个父类(可以是抽象类),一个类可以实现多个接口
                    类与类之间只能是单继承关系,接口与接口之间可以是多继承
                    抽象类定义普通的成员变量,接口只能定义常量 public static final修饰的
                    抽象类有构造方法,接口没有构造方法
                    抽象类有静态代码块,接口中没有静态代码块
                   

推荐阅读