【java】抽象类 和 接口

  • 抽象类
Java提供一个叫抽象方法的机制,这种方法是不完整的,仅有声明体而没有方法体。即:
abstract void f();     
包含抽象方法的的类叫做抽象类。如果一个类包含一个或者多个抽象方法,该类必须限定为抽象的。
创建抽象类和抽象方法非常有用,因为它们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样来使用它们。
抽象类还是很有用的重构工具,因为它们使我们可以很容易地将公共方法沿着继承层次向上移动。

  • 接口
可以在接口关键字前面添加public,不添加的话,默认为包访问权限。
接口中,方法不添加关键字的话,则默认为public。
【代码:Music5.java】
package source.gohome01;
import source.saterday.Note;

interface Instrument {
	int VALUE = 5;	//static && final
	void play(Note n);	//Automatically public 
	void adjust();
}
class Wind implements Instrument {
	public void adjust() { System.out.println(this + ".adjust()");	}
	public void play(Note n) {	System.out.println(this + ".play()" + n); }	
	public String toString() { return "Wind"; }
}

class Percussion implements Instrument {
	public void adjust() { System.out.println(this + ".adjust()");	}
	public void play(Note n) {	System.out.println(this + ".play()" + n); }	
	public String toString() { return "Percussion"; }
}

class Stringed implements Instrument {
	public void adjust() { System.out.println(this + ".adjust()");	}
	public void play(Note n) {	System.out.println(this + ".play()" + n); }	
	public String toString() { return "Stringed"; }
}
class Brass extends Wind {
	public String toString() { return "Brass"; }
}
class WoodWind extends Wind {
	public String toString() { return "WoodWind"; }
}

public class Music5 {
	static void tune(Instrument i) {
		i.play(Note.MIDDLE_C);
	}
	static void tuneAll(Instrument[] e) {
		for(Instrument i: e)
			tune(i);
	}
	public static void main(String[] args) {
		Instrument[] orchestra = {
				new Wind(),
				new Percussion(),
				new Stringed(),
				new Brass(),
				new WoodWind()
		};
		tuneAll(orchestra);
	}
}

output:

  • 利用接口实现完全解耦
【代码Apply.java】:利用了策略设计模式。
package source.gohome01;

import java.util.Arrays;

class Processor {
	public String name() { 
		return getClass().getSimpleName();
	}
	Object process(Object input){
		return input;	//Object是所有类的基类,此方法可以在导出类中将返回值和形参改为具体类型
	}
}
class Upcase extends Processor {
	String process(Object input) {
		return ((String)input).toUpperCase();
	}
}
class Downcase extends Processor {
	String process(Object input) {
		return ((String)input).toLowerCase();
	}
}
class Splitter extends Processor {
	//the split() argument divides a String into pieces.
	String process(Object input) {
		return Arrays.toString(((String)input).split(" "));
	}
}
public class Apply {
	public static void process(Processor p, String s) {
		System.out.println("Using Processor: " + p.name());
		System.out.println(p.process(s));
	}
	public static String s = 
		"Disagreement with beliefs is by definition incorrect";
	public static void main(String[] args ) {
		process(new Upcase(), s);
		process(new Downcase(), s);
		process(new Splitter(), s);
	}
}	// 此为策略模式:创建一个能够根据所传递的参数对象的不同而具有不同行为的方法。
	//new Upcase(),new Downcase(),new Splitter()均导出自Processor(),从而实现多态。

output:

加入想复用Apply.process() 的代码,但是由于该函数原型为:
public  static   void  process(Processor p, String s)
第一个参数必须导出自Processor才可以,所以此时如果将Processor改为接口则使用起来更为方便。
【代码StringProcessor.java】
package source.gohome01;
import java.util.Arrays;
class Apply01 {
	public static void process(Processor01 p, Object s) {
		System.out.println("Using Processor: " + p.name());
		System.out.println(p.process(s));
	}
}	
interface Processor01 {
	String name();
	Object process(Object input);
}

class Upcase01 extends StringProcessor {
	public String process(Object input) {
		return ((String)input).toUpperCase();
	}
}
class Downcase01 extends StringProcessor {
	 public String process(Object input) {
		return ((String)input).toLowerCase();
	}
}
class Splitter01 extends StringProcessor {
	//the split() argument divides a String into pieces.
	public String process(Object input) {
		return Arrays.toString(((String)input).split(" "));
	}
}
public abstract class StringProcessor implements Processor01{
	public String name() {
		return getClass().getSimpleName();
	}
	public abstract Object process(Object input) ;
	public static String s = 
		"If she weighs the smae as a duck,she's made of wood.";
	public static void main(String[] args ) {
		Apply01.process(new Upcase01(), s);
		Apply01.process(new Downcase01(), s);
		Apply01.process(new Splitter01(), s);
	}
}
//Apply.process 的第一个参数改为接口类型
//客户端遵循接口来编写自己的类 StringProcessor,其他类继承之

output:


为了解决耦合问题,也可以使用适配器模型,详见《Thinking in Java》P177

  • 接口中的域
接口中的任何域都是static和final的,所以接口就成为了一种很便捷的用来创建常量组的工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值