• Java_接口与抽象类


    接口:

    接口,英文interface,在java中,泛指供别人调用的方法或函数。接口是对行为的一种抽象。

    语法:

    [public] interface InterfaceName{}

    注意:

    1)接口中的变量会被隐式(只能)定义为 public static final;

    2)接口中的方法会被隐式(只能)定义为 public abstract;

    3)接口中的所有方法都不能有具体实现(只能是抽象方法);

    4)接口不能实例化(因为接口中的方法都是抽象的,没有方法体);

    5)一个类可以实现多个接口(用 , 分隔);

    6)接口可以继承一个或多个其他接口;

    7)一个类要实现某个接口,必须实现接口中的所有方法。

     

    为什么一定要使用接口?

    1)接口被用来描述一种行为的抽象;

    2)java只支持单继承,但可以通过接口来弥补这一缺陷;

    3)接口也被用来解耦。

    一个栗子:

    public interface CalInterface {
    	public static final float PI=3.1415926f;
    	public abstract float getArea(float r);
    	float getCircumference(float r);
    }
    
    public class Cire implements CalInterface{
    
    	public float getArea(float r) {
    		float s = PI*r*r;
    		return s;
    	}
    
    	public float getCircumference(float r) {
    		float c = 2*PI*r;
    		return c;
    	}
    	
    	public static void main(String[] args) {
    		Cire cire = new Cire();
    		float area = cire.getArea(7.8f);
    		System.out.println("圆的面积是:"+area);
    		
    		float cm = cire.getCircumference(7.8f);
    		System.out.println("圆的周长是:"+cm);
    	}
    }
    

     控制台输出:

    圆的面积是:191.13449
    圆的周长是:49.008842
    

     

    抽象类:

    抽象方法:抽象方法是一种特殊的方法,它只有声明而没有具体的实现。

    格式:

    abstract void fun();

    注意:

    1)抽象方法必须使用abstract关键字来修饰;

    2)如果一个类中含有抽象方法,则称这个类为抽象类,抽象类必须用abstract关键字修饰;

    3)抽象类中含有无具体实现的方法,所以,不能使用抽象类创建对象(抽象类不能实例化);

    4)抽象类中不仅只包含抽象方法,同样也可以拥有成员变量和普通的成员方法。

     

    抽象类与普通类的区别?

    1)抽象方法必须由public或protected修饰,缺省条件下默认为public;

    2)抽象类不能用来创建对象;

    3)如果一个类继承抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。

    除了这三点,抽象类与普通类并没什么区别。

    格式:

    [public] abstract class ClassName{

      abstract void fun();

    }

    关于抽象类与接口的区别?

    1、语法层面上的区别:

    1)抽象类可以提供成员方法的实现细节,而接口中只能存在 public abstract方法;

    2)抽象类中的成员变量可以是各种类型的,而接口中只能是 public static final 类型;

    3)抽象类中可以有静态代码块和静态方法,而接口中不能有静态代码块或静态方法;

    4)一个类只能继承一个抽象类,而一个类可以实现多个接口。

    2、设计层面上的区别:

      抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对一个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是会飞。那么我们在设计的时候,可以将飞机设计为类Airplane,将鸟设计为类Bird,但是不能将飞行这个特性也设计为类,因为它只是一个行为特征,并不是对一类事物的抽象描述。此时可以将飞行设计成接口Fly,包含方法fly(),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机,民用飞机等直接继承Airplane即可,对于鸟也是类似的,直接继承Bird即可。从这里可以看出,继承是一个“是不是”的关系,而接口实现则是一个“有没有”的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有,具不具备的关系,比如鸟是否能飞,能飞则实现Fly接口,不能飞就不用实现。

      抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?举个最简单的例子,如果用PPT模板A设计了PPT B 和PPT C ,那么B和C的公共部分就是A了,如果它们的公共部分需要改动,则只需要改动模板A即可,不需要重新对B和C进行改动。而辐射式设计,比如某个电梯都安装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说,对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,那实现这个接口的全部类都必须进行相应的变更。

    一个栗子:

    是网上最流行的门与警报的栗子:门都有open()和close()两个动作,现在我们需要门有报警alarm()功能,那我们该如何实现?下面提供两种思路:

    1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警的功能,但有时候门不需要报警的功能;

    2)将这三个类都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open(),close(),但也许这个类根本就不具备这两个功能,比如火灾报警器。

    从上面分析我们知道,Door的open(),close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特征,而alarm()属于延伸的附加行为,因此最好的解决办法就是单独将报警设计为一个接口,包含alarm()行为,Door设计为一个抽象类,包含open,close两种行为。再设计一个报警门继承Door类实现Alarm接口。

    public abstract class Door {
    	abstract void open();
    	abstract void close();
    }
    
    public interface Alarm {
    	void alarm();
    }
    
    public class AlarmDoor extends Door implements Alarm{
    
    	@Override
    	public void alarm() {
    		// TODO Auto-generated method stub
    	}
    	@Override
    	void open() {
    		// TODO Auto-generated method stub
    	}
    	@Override
    	void close() {
    		// TODO Auto-generated method stub
    	}
    }
    

     

    贴一张抽象类与接口的对比图:

     

    参考:https://www.cnblogs.com/dolphin0520/p/3811437.html

    图:http://www.importnew.com/12399.html

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    windows 10下ELK环境快速搭建实践
    Windows 10下搭建以太坊私有链环境
    线程状态转换图
    JAVA中IO技术:BIO、NIO、AIO
    MySQL MDL锁的阻塞问题 & online ddl的插队现象【转发】
    MySQL InnoDB MVCC 能否完全解决幻读?
    Linux 计算 存储 网络 统计命令
    MySQL B+ tree & B tree & Hash
    mmap学习总结
    Linux内存分配小结--malloc、brk、mmap【转】
  • 原文地址:https://www.cnblogs.com/Rain1203/p/10756085.html
Copyright © 2020-2023  润新知