• (三)、抽象类和接口的区别


    一、抽象类(Abstract Class)

    (一)概念

    1.抽象类是关键字Abstract修饰的类,即为抽象类,但是没有方法体( 没有{ } ),只有声明方法,抽象方法强制子类覆盖。

    2.抽象抽象即不能被实例化,不能创建对象(不能new, 但是可以super)。而不能被实例化就无用处,所以抽象类只能作为基类(父类),即被继承的类,即抽象类必须得有子类,自己的功能才能得以运行。

    3.抽象类中可以包含抽象方法也可以不包含,但具有抽象方法的类一定是抽象类。

    4.抽象类的方法只是定义了子类应该具备的行为,但是没有给出怎么去完成行为的功能代码,要交给子类去根据自身特殊情况去完成该父类申明的功能。

    5.抽象类中可以有普通方法,可以声明成员变量。

    (二)抽象类的使用原则

    1.被继承性:抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;

    2.抽象性:抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;

    3.抽象类必须要有子类,使用extends继承;

    4.子类(如果不是抽象类)则必须重写抽象类中的全部抽象方法;如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。

    5.抽象类中的普通方法可以有选择型的来决定是否需要重写。

    //抽象类
    abstract class A{
        //普通方法
        public void fun(){    
            System.out.println("存在方法体的方法");
        }
        //抽象方法,没有方法体,有abstract关键字作修饰
        public abstract void print();
    }
    //单继承特性
    class B extends A{  //B类是抽象类的子类,是一个普通类
        @Override
        public void print(){    //强制要求重写
            System.out.println("Why is more important than what!");
        }
    }
    //主函数
    public class test{
        public static void main(String[] args) {
            A a = new B();     //多态,向上转型
            a.print();
            a.fun(); //被子类所重写过的方法
        }
    }

    运行结果如下:

    (三)为什么不能进行实例化?

    当一个类实例化后,就意味着对象可以调用类中的属性或者方法,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用,既然无法进行方法调用,又怎么去产生实例化对象呢。

    (四)抽象类的使用限制

    1.抽象类中有构造方法吗?

      由于抽象类里会存在一些属性,那么抽象类一定存在构造方法,其存在目的就是为了属性的初始化。并且子类对象实例化的时候,依然满足先执行父类构造,再执行子类构造的顺序。

    abstract class A{//定义一个抽象类
        
        public A(){
            System.out.println("*****A类构造方法*****");
        }
    
        public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
        
    }
    
    //单继承
    class B extends A{//B类是抽象类的子类,是一个普通类
    
        public B(){
            System.out.println("*****B类构造方法*****");
        }
    
        @Override
        public void print(){//强制要求覆写
            System.out.println("Hello World! ");
        }
    }
    
    public class TestDemo{
        public static void main(String[] args) {
            A a = new B(); //向上转型
        }
    }   //最后依次输出A类和B类的构造方法

    运行结果如下:

    2.抽象类中可以用final声明吗?

      不能,因为抽象类必须有子类,而final声明的类不能有子类。

    3.抽象类能否用static声明?

      外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。

      用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用"外部类.内部类"的形式表示类名称

    abstract class A{//定义一个抽象类
        
        static abstract class B{//static定义的内部类属于外部类
            public abstract void print();
        }
        
    }
    
    class C extends A.B{
        
        public void print(){
            System.out.println("**********");
        }
    }
    public class TestDemo {
    
        public static void main(String[] args) {
            A.B ab = new C();//向上转型
            ab.print();
        }
    
    }

    运行结果如下:

    4.可以直接调用抽象类中用static声明的方法么?

      任何时候,如果要执行类中的static方法的时候,都可以在没有对象的情况下直接调用,对于抽象类也一样。 

    abstract class A{    //定义一个抽象类
    
        public static void print(){
            System.out.println("Hello World !");
        }
    
    }
    
    public class TestDemo{
        public static void main(String[] args) {
            A.print();
        }
    }

    运行结果如下:

    5.有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略外部子类。

      这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。

    abstract class A{    //定义一个抽象类
    
        public abstract void print();
    
        private static class B extends A{    //内部抽象类子类
    
            public void print(){    //覆写抽象类的方法
                System.out.println("Hello World !");
            }
        }
    
        //这个方法不受实例化对象的控制
        public static A getInstance(){
            return new B();
        }
    }
    
    public class TestDemo{
        public static void main(String[] args) {
            //此时取得抽象类对象的时候完全不需要知道B类这个子类的存在
            A a = A.getInstance();
            a.print();
        }
    }

    运行结果如下:

    (五)抽象类的应用——模板设计模式 

      所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

    二、接口(Interface)

    接口在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

    接口定义了一种规范,规定一个类必须做什么,但是不管如何具体去做。

    (一)接口与类相似点

      一个接口可以有多个方法;

      接口文件保存在 .java 结尾的文件中,文件名使用接口名。

      接口的字节码文件保存在 .class 结尾的文件中。

      接口相应的字节码文件必须在与包名称相匹配的目录结构中。

    (二)接口与类的区别

      接口不能实例化对象;

      接口没有构造方法;

      接口中的所有方法必须是抽象方法;

      接口不能包含成员变量,除了static和final变量;

      接口不是被类继承了,而是要被类实现;

      接口支持多继承;

      接口只能继承接口,不能继承类;

      接口里的方法默认修饰符是public abstract;

      接口里的字段全是全局变量,默认修饰符是public static final。

    (三)接口特性

      接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

      接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

      接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

    (四)接口的继承

    当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

    Java中类不允许多继承但接口可以。

    // 文件名: Sports.java
    public interface Sports
    {
       public void setHomeTeam(String name);
       public void setVisitingTeam(String name);
    }
     
    // 文件名: Football.java
    public interface Football extends Sports
    {
       public void homeTeamScored(int points);
       public void visitingTeamScored(int points);
       public void endOfQuarter(int quarter);
    }
     
    // 文件名: Hockey.java
    public interface Hockey extends Sports
    {
       public void homeGoalScored();
       public void visitingGoalScored();
       public void endOfPeriod(int period);
       public void overtimePeriod(int ot);
    }

    (五)接口的实现

    当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

    类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

    /* 文件名 : Animal.java */
    interface Animal {
       public void eat();
       public void travel();
    }
    
    /* 文件名 : test.java */
    public class MammalInt implements Animal{
     
       public void eat(){
          System.out.println("Mammal eats");
       }
     
       public void travel(){
          System.out.println("Mammal travels");
       } 
     
       public int noOfLegs(){
          return 0;
       }
     
       public static void main(String args[]){
          test m = new test();
          m.eat();
          m.travel();
       }
    }

    运行结果如下:

    三、抽象类与接口的区别

    很想高飞,但我不能;不想天空,剩我一人。
  • 相关阅读:
    2018个人面试记录
    如何用纯代码实现图片CSS3
    JS数组删除
    JS数组去重
    HTML--使用提交按钮,提交数据
    HTML--使用下拉列表框进行多选
    HTML--使用下拉列表框,节省空间
    HTML--使用单选框、复选框,让用户选择
    HTML--文本域,支持多行文本输入
    HTML--文本输入框、密码输入框
  • 原文地址:https://www.cnblogs.com/lixiansheng/p/11299713.html
Copyright © 2020-2023  润新知