抽象类与接口

      1、final 

/*
	final修饰类与方法
	当类声明为final时,该类为终极类(类的最终版本),
	不能被子类所继承。
	当方法声明为final时,该方法为终极方法(方法的最终
	版本),不能被子类所重写。

	final的应用:
	1 某些方法(类)已经实现的很完善,不需要子类再去
	扩展。
	2 处于安全考虑,阻止子类去修改父类的实现。

	当一个类声明为final时,类中所有的方法都隐式为final。

	当方法是final时,由于该方法不能被子类重写,
	在编译期间就可以决定调用哪一个方法,因此可以
	提高一定的性能。
*/

public class FinalTest {
	public static void main(String[] args) {
		
	}

	public void doSomething(Super s) {
		s.f();
	}
}

class Super {
	public final void f() {

	}
}

class Sub extends Super {
	/*@Override
	public void f() {

	}
	*/
}

/*
final class Super {

}
错误,final类不能被子类继承。
class Sub extends Super {

}
*/

  2、抽象类与抽象方法     

/*
	抽象类与抽象方法
	抽象类与抽象方法使用abstract修饰。
	当类中某些功能(方法)不方便(或不知道)给出具体
	实现,如果实现时,我们就可以将该类声明为抽象类。
	而不方便(不知道)实现的方法声明为抽象方法。

	抽象方法没有方法体。({}也没有)

	抽象类是一个实现不完整的类,其设计的目的
	就是为了让子类去继承的。抽象方法设计的目的
	就是为了让子类去重写的(当父类的方法是抽象方法时,
	也习惯说成子类实现父类的方法。)。

	当类中含有抽象方法时,该类必须要声明为抽象类。
	反之,当一个类声明为抽象类时,该类可以没有抽象
	方法。

	我们不能够创建抽象类的对象。(抽象类是实现不完整的类。)
	但是,我们依然可以声明抽象类的引用,使其指向子类
	的对象。

	当子类继承了抽象的父类,子类就必须要实现抽象父类中
	所有的抽象方法。否则,子类就需要也要声明为抽象类。
*/
public class AbstractTest {
	public static void main(String[] args) {
		//错误,抽象类不能创建对象(实例化)。
		//Shape s = new Shape();
		//s.pe();
		Shape s = new Rectangle();
	}
}

abstract class Shape {
	//抽象方法
	public abstract double pe();

	public abstract double area();
}

class Rectangle extends Shape {
	
}

  3、接口类型

          

/*
	接口类型
	接口只的是一种规范,该规范指出各个实现者
	能够做到什么样的结果,而具体实现的细节,各个
	实现者可以根据需要各自的需要灵活进行控制。

	接口声明:
	interface
	接口表示一种规范,该规范是通过接口中的抽象方法
	来声明。该规范有类(class)来实现(implmenets)。
	如果一个类实现了接口,则该类必须遵守接口中声明
	的规范。即类需要实现接口中所有的抽象方法。否则,
	该类必须声明为抽象类。



*/
public interface School {
	//按时到校的规范
	abstract void goToSchool();
}

//小学生
class StudentA implements School {
	@Override
	public void goToSchool() {
		System.out.println("走路上学");
	}
}

//幼儿园学生
class StudentB implements School {
	@Override
	public void goToSchool() {
		System.out.println("家长送上学");
	}
}

//大学生
class StudentC implements School {
	@Override
	public void goToSchool() {
		System.out.println("逃学");
	}
}

  4、接口的成员

/*
	接口中的成员
	接口中可以声明变量(常量),抽象方法,
	默认方法,静态方法,内部类型(不考虑)。

	1 接口中声明的成员变量一律是public,
	static,final类型的。
	2 接口中声明的普通方法一律是public,
	abstract类型的。
	3 即使1,2中的关键字不显式声明也是如此。
	根据惯例,省略以上的关键字。

	接口中所有的成员都是public类型的。无论我们
	是否显式声明都是如此。
*/

interface Member {
	//public static final int x = 1;
	int x = 1;	//成员变量
	//public abstract void f();
	void f();	//抽象方法
	
	//默认方法,具有具体的实现。(方法体)
	default void defF() {
		System.out.println("我是默认方法,具有实现");
	}

	//静态方法,具有具体的实现。(方法体)
	static void staF() {
		System.out.println("我是静态方法,具有实现");
	}
}

  5、接口的继承      

/*
	接口的继承
	接口的继承与类的继承不同。在Java中,类只支持
	单继承,即一个子类只能继承一个父类,而接口支持
	多继承,即一个子接口可以同时继承多个父接口。

	当子接口继承父接口,子接口会继承父接口中的成员。
	子接口可以继承父接口中的成员变量,抽象方法,
	默认方法,但是,不能继承父接口中的静态方法。
	对于接口中声明的静态方法,直通通过声明该静态方法的
	接口名进行访问。
*/

interface SupInter1 {
	int x = 5;
	void f();
	default void defF() {

	}

	static void staF() {

	}
}

interface SupInter2 {
	int y = 10;
}

interface SubInter extends SupInter1 {
	default void defF2() {
		System.out.println(x);
		f();
		SupInter1.staF();
		//错误,不能继承静态方法。
		//staF();
		//SubInter.staF();
	}
}

//接口的多继承,使用“,”分隔。
interface SubInter2 extends SupInter1, SupInter2 {
	default void defF3() {
		System.out.println(x);
		System.out.println(y);
	}
}

  6、接口的实现

/*
	接口的实现
	接口设计的目的是为了让实现类去实现的。
	类使用implements实现接口,一个类可以
	实现多个接口,使用","进行分隔。
	当一个类实现了某个接口,该类就会成为
	接口的子类型(接口成为该类的父类型),
	类可以继承接口中声明的成员。
	类可以继承接口中声明的成员变量,抽象方法,
	默认方法。但是,类不能继承接口中声明的静态方法。

	因为接口中含有抽象的方法,所以,我们也不能创建
	接口类型的对象。尽管如此,我们依然可以声明接口
	类型的引用,令其指向实现类的对象。

	通过父类型的引用,不能访问子类型新增的成员。
	1 通过父类的引用,不能访问子类新增的成员。
	2 通过接口的引用,不能访问实现类新增的成员。
*/
interface InterA {
	int x = 1;
	void f();
	default void defF() {
		
	}

	static void staF() {
		
	}
}

class ImplClass implements InterA {
	@Override
	public void f() {
		System.out.println("实现抽象方法。(实现规范细节)");
	}

	public void g() {
		System.out.println(x);
		f();
		defF();
		//错误,类没有继承接口中的静态方法。
		//staF();
		
		//错误,不能创建接口类型的对象。
		//InterA a = new InterA();
		InterA a = new ImplClass();
		a.f();
		//错误
		//a.g();
	}
}

  7、求周长案例

interface Shape {
	//可以求周长
	double pe();
	//可以求面积
	double area();
}

class Rectangle implements Shape {
	private double width;
	private double height;

	public Rectangle(double width, double height) {
		this.width = width;
		this.height = height;
	}
	
	@Override
	public double pe() {
		return (width + height) * 2;
	}

	@Override
	public double area() {
		return width * height;
	}
}

class Triangle implements Shape {
	private double length;

	public Triangle(int length) {
		this.length = length;
	}

	@Override
	public double pe() {
		return length * 3;
	}

	@Override
	public double area() {
		double height = length * length - (length / 2) * (length / 2);
		height = Math.sqrt(height);
		return length * height / 2;
	}
}

class Circle implements Shape {
	private double radius;

	public Circle(double radius) {
		this.radius = radius;
	}

	@Override
	public double pe() {
		return 2 * Math.PI * radius;
	}

	@Override
	public double area() {
		return Math.PI * radius * radius;
	}
}

class Test {
	public void compute(Shape s) {
		System.out.println(s.pe());
		System.out.println(s.area());
	}

	public static void main(String[] args) {
		Test t = new Test();
		t.compute(new Rectangle(10, 5));
		t.compute(new Triangle(5));
		t.compute(new Circle(5));
	}
}

  8、子接口与默认方法

/*
	子接口与默认方法
	接口作为一种规范,一旦发布,就不能随意进行更改。
	否则就会对各个实现者造成很大的影响。
	
	怎样升级可以不对实现者造成影响:
	1 使用子接口继承现有的接口,发布一个新的规范(对
	原有规范的一个升级)
	2 从JavaSE 8起,也可以选择第二种升级方法:增加
	默认方法。
*/

//1000
interface Car {
	void run();
	//1002
	//void fly();
	default void fly() {
		System.out.println("默认方式的飞");
	}
}

/*
interface FlyCar extends Car {
	//新增的规范
	void fly();
}
*/

//1001
class CarA implements Car {
	@Override
	public void run() {
		System.out.println("汽车跑动");
	}

	/*
	@Override
	public void fly() {
		System.out.println("自己实现的飞的方式");
	}
	*/
}

/*
class CarA implements FlyCar {
	@Override
	public void run() {
		System.out.println("汽车跑动");
	}

	@Override
	public void fly() {
		System.out.println("汽车飞");
	}
}

  9、面向接口编程案例

现需要开发一个应用,模拟移动存储设备的读写,既计算机与
U盘、 MP3、移动硬盘等设备进行数据交换(读写操作)。
 要实现U盘、 MP3、移动硬盘三种移动存储设备,要求计算机
能同这三种设备进行数据交换。
 并且以后可能会有新的第三方的移动存储设备,所以计算机
必须有扩展性,能与目前未知而以后可能会出现的存储设备
进行数据交换。
 各个存储设备间读、写的实现方法不同, U盘和移动硬盘只
有读,写这两个方法, MP3Player还有一个playMusic方法。

  

    方案1:  

public class Case1 {
	public static void main(String[] args) {
		Computer c = new Computer();
		c.read(new FlashDisk());
		c.read(new MP3Player());
		c.read(new MobileHardDisk());

		c.write(new FlashDisk());
		c.write(new MP3Player());
		c.write(new MobileHardDisk());
	}
}

class FlashDisk {
	public void read() {
		System.out.println("U盘读");
	}

	public void write() {
		System.out.println("U盘写");
	}
}

class MP3Player {
	public void read() {
		System.out.println("MP3读");
	}

	public void write() {
		System.out.println("MP3写");
	}
}

class MobileHardDisk {
	public void read() {
		System.out.println("移动硬盘读");
	}

	public void write() {
		System.out.println("移动硬盘写");
	}
}

class Computer {
	public void read(FlashDisk f) {
		f.read();
	}

	public void read(MP3Player mp3) {
		mp3.read();
	}

	public void read(MobileHardDisk m) {
		m.read();
	}

	public void write(FlashDisk f) {
		f.write();
	}

	public void write(MP3Player mp3) {
		mp3.write();
	}

	public void write(MobileHardDisk m) {
		m.write();
	}
}

  方案2:

public class Case2 {
	public static void main(String[] args) {
		Computer c = new Computer();
		c.setMs(new FlashDisk());
		c.readData();
		c.writeData();
		c.setMs(new MP3Player());
		c.readData();
		c.writeData();
		c.setMs(new MobileHardDisk());
		c.readData();
		c.writeData();
	}
}

abstract class MobileStorage {
	public abstract void read();

	public abstract void write();
}

class FlashDisk extends MobileStorage {
	@Override
	public void read() {
		System.out.println("U盘读");
	}

	@Override
	public void write() {
		System.out.println("U盘写");
	}
}

class MP3Player extends MobileStorage {
	@Override
	public void read() {
		System.out.println("MP3读");
	}

	@Override
	public void write() {
		System.out.println("MP3写");
	}

	public void playMusic() {
		System.out.println("MP3所特有的功能,播放音乐!");
	}
}

class MobileHardDisk extends MobileStorage {
	@Override
	public void read() {
		System.out.println("移动硬盘读");
	}

	@Override
	public void write() {
		System.out.println("移动硬盘写");
	}
}

class Computer {
	private MobileStorage ms;

	public void setMs(MobileStorage ms) {
		this.ms = ms;
	}

	public MobileStorage getMs() {
		return ms;
	}

	public void readData() {
		ms.read();
		if (ms instanceof MP3Player) {
			MP3Player mp3 = (MP3Player) ms;
			mp3.playMusic();
		}
	}

	public void writeData() {
		ms.write();
	}
}

  方案3:

public class Case3 {
	public static void main(String[] args) {
		Computer c = new Computer();
		c.setMs(new FlashDisk());
		c.readData();
		c.writeData();
		c.setMs(new MP3Player());
		c.readData();
		c.writeData();
		c.setMs(new MobileHardDisk());
		c.readData();
		c.writeData();
	}
}

interface IMobileStorage {
	void read();

	void write();
}

class FlashDisk implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("U盘读");
	}

	@Override
	public void write() {
		System.out.println("U盘写");
	}
}

class MP3Player implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("MP3读");
	}

	@Override
	public void write() {
		System.out.println("MP3写");
	}
}

class MobileHardDisk implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("移动硬盘读");
	}

	@Override
	public void write() {
		System.out.println("移动硬盘写");
	}
}

class Computer {
	private IMobileStorage ms;

	public void setMs(IMobileStorage ms) {
		this.ms = ms;
	}

	public IMobileStorage getMs() {
		return ms;
	}

	public void readData() {
		ms.read();
	}

	public void writeData() {
		ms.write();
	}
}

  方案4:

public class Case4 {
	public static void main(String[] args) {
		Computer c = new Computer();
		c.setMs(new FlashDisk());
		c.readData();
		c.writeData();
		c.setMs(new MP3Player());
		c.readData();
		c.writeData();
		c.setMs(new MobileHardDisk());
		c.readData();
		c.writeData();
	}
}

interface IReadable {
	void read();
}

interface IWritable {
	void write();
}

interface IMobileStorage extends IReadable, IWritable {

}

class FlashDisk implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("U盘读");
	}

	@Override
	public void write() {
		System.out.println("U盘写");
	}
}

class MP3Player implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("MP3读");
	}

	@Override
	public void write() {
		System.out.println("MP3写");
	}
}

class MobileHardDisk implements IMobileStorage {
	@Override
	public void read() {
		System.out.println("移动硬盘读");
	}

	@Override
	public void write() {
		System.out.println("移动硬盘写");
	}
}

class Computer {
	private IMobileStorage ms;

	public void setMs(IMobileStorage ms) {
		this.ms = ms;
	}

	public IMobileStorage getMs() {
		return ms;
	}

	public void readData() {
		ms.read();
	}

	public void writeData() {
		ms.write();
	}
}

  

原文地址:https://www.cnblogs.com/liuwei6/p/6572082.html