zoukankan      html  css  js  c++  java
  • 21java的抽象类和接口

    抽象类

    • 我们先来看抽象类的实现实例,然后再讨论关于抽象类的细节问题。

    package oop.OopDemo.AbstractClass;
    
    public class TestAbstract {
        public static void main(String[] args) {
            //Animal animal = new Animal();//报错
            Animal animal = new Student();
            animal.run();
        }
    }
    
    package oop.OopDemo.AbstractClass;
    
    public abstract class Animal {
        public abstract void run();//有抽象方法必须是抽象类
        public void speak() {//抽象类里面可以定义普通方法
            System.out.println("AbstractClass is speaking!");
        }
        public String name;
        public Animal() {
        	System.out.println("父类的构造方法");
        }
    }
    
    class Student extends Animal {
        public void run() {
            System.out.println("Student is running!");
        }
    }
    
    class Person extends Animal {
        @Override
        public void run() {
            System.out.println("Person is running!");
        }
    }
    

    运行结果:

    下面分析一下这个抽象类的程序 :

    1. 什么是抽象类?
      • 抽象类是一种模板模式,为继承它的子类提供一个通用模板,子类必须实现抽象类里面的所有抽象方法。子类也可以拓展自己的属性和方法。
    2. 抽象类的要点:
      • 有抽象方法的类只能定义成抽象类。
      • 抽象类不能被实例化(不能使用new关键字创建一个对象),但是可以使用父类的引用指向子类的对象创建一个子类对象(注意:此时创建的对象在编译时是父类对象,运行时是子类对象)。
      • 子类必须重写抽象类里面的抽象方法。
      • 抽象类只能用来继承。
      • 抽象类除了包含抽象方法,还有普通属性、方法和构造方法,但是构造方法不能被new实现,只能使用父类的引用指向子类的对象进行调用。
    3. 抽象类存在的意义是什么?
      • 通过继承抽象类,可以避免子类设计的随意性,可以做到严格限制子类的设计,使子类之间更加通用。
      • 把抽象方法的设计和方法的实现分开了。在抽象父类里面制定了一系列的方法(模板),然后又继承它的子类实现这些方法,具体怎么实现根据子类的需求。

    接口

    • 我们使用继承描述动物和猫、狗、猪等等的联系,但是如果描述:飞机,石头,篮球等的关系该如何描述?

    • 上面的抽象类还是不够抽象,因为抽象类里面还能写普通的方法,如何更加的抽象(更具有一般性)?

    能不能设计一个新的概念,这个概念没有方法,只有方法的声明(抽象方法和常量),这就是比抽象类还要抽象的类——接口interface

    下面看接口的程序实例:

    package oop.OopDemo.Interface;
    
    public interface MyInterface {//编译之后还会产生.class文件,本质上和类相同
        //接口中只有两个东西:常量、抽象方法
         String name = "fada";//接口中常量默认前缀 public static final,写不写都行
         double PI = 3.14159;
         void run();//接口中,方法默认是public abstract
         double sum(double num1,double num2);
    }
    
    package oop.OopDemo.Interface;
    
    public interface Flyable {//接口中只有常量和抽象方法
        int FLY_SPEED=100;
        int FLY_HEIGHT=2;
    
        void fly();
        void fuelLoss();
    }
    
    package oop.OopDemo.Interface;
    
    public interface Attack extends Flyable{//接口可以继承,并且支持多继承
        char isHit = '0';//是否击中
        void attack();
    }
    
    package oop.OopDemo.Interface;
    
    public class Plane implements Flyable ,Attack{
        @Override
        public void fly() {
            System.out.println("Plane is flying!");
        }
    
        @Override
        public void fuelLoss() {
            System.out.println("Plane's fuelLoss is high!");
        }
    
        public void attack() {
            System.out.println("The plane is hitting!");
        }
    }
    
    package oop.OopDemo.Interface;
    
    public class Human implements Flyable {
        public void fly() {
            System.out.println("I'm a person, I'm flying!");
        }
    
        public void fuelLoss() {
            System.out.println("Just need eat meal!");
        }
    }
    
    package oop.OopDemo.Interface;
    
    public class Stone implements Flyable,Attack,MyInterface{//可以实现多个接口
        @Override
        public void fly() {//重写它实现的接口的所有方法
            System.out.println("Stone was throwing!");
        }
    
        @Override
        public void fuelLoss() {
            System.out.println("Stone is not fueling!");
        }
    
        @Override
        public void attack() {
            System.out.println("Stone can attacking!");
        }
    
        @Override
        public void run() {
    
        }
    
        @Override
        public double sum(double num1, double num2) {
            return 0;
        }
    }
    

    为了能够充分说明接口的属性和用法,上面给出了六个接口/类。

    首先,前三个程序是定义了三个接口,后面三个程序是实现(implements)这些接口的类。下面作总结:

    • 接口使用关键字interface,接口本质上和类文件时相同的,编译之后也会产生.class 文件;

    • 接口比类更加抽象,接口中只能有两个东西:抽象方法,常量,

      且常量的默认前缀是:public static final,方法的默认前缀是:public abstract

    • 可以使用类来实现(implements)接口但是类不能继承(extends)接口接口可以继承接口,一个接口继承了另一个接口,同类的继承,就拥有了这个接口的所有属性和方法。

    • 接口的继承(extends)可是使用多继承,接口的实现(implements)可以使用多实现。

    • 一个类实现(implements)一个接口,就必须实现这个接口中的所有方法,并且方法之只能是public的。

    • 接口不能创建实例,但是可用于声明引用变量类型,下面截取一些程序片段作说明:

    public class Stone implements Flyable,Attack,MyInterface{//可以实现多个接口
        int num=0;
        @Override
        public void fly() {
            System.out.println("Stone was throwing!");
        
    
    package oop.OopDemo.Interface;
    
    public class Test {
        public static void main(String[] args) {
            MyInterface myInterface= new Stone();
            System.out.println(myInterface.num);//报错:Cannot resolve symbol 'num'
        }
    }
    
    • Stone类实现(implements)了 Flyable , Attack , MyInterface 三个接口,拥有了这三个接口所有的常量和抽象方法,必须实现所有的抽象方法。

    • 我在Stone类里面定义了一个int型的变量,在Test类里面使用父类引用指向子类对象,实例化了一个变量,变量类型是Stone类,但是这个变量不能访问Stone类的属性num,这是为什么?

      因为,myInterface的编译时类型是MyInterface,而 MyInterface接口中并没有int型的num属性,所以编译就不通过。

    Post Script:以后代码可能会越来越长,我会同步把代码比较多的project或者package直接push到个人github,您可以直接访问下载或者提交更好的版本。
    github地址:

    https://github.com/fanfada/Interface
    
    自学java,请多多指教!
  • 相关阅读:
    Project 01 PlantAndZomb
    iOS平台内存使用原则
    IOS之UIKit_Day22--23
    IOS之UIKit_Day21
    IOS之UIKit_Day20
    浅谈javascript数据类型,对象,类
    从输入一个url到加载页面发生了什么?
    d3.js(2)-svg
    d3.js(1)
    console.time和performance.now()
  • 原文地址:https://www.cnblogs.com/fanfada/p/13823483.html
Copyright © 2011-2022 走看看