接口笔记一
抽象类
只有声明而没有方法体的不完整方法叫做抽象方法,含有抽象方法的类叫做抽象类。但是抽象类也可以没有抽象方法,这里使用抽象方法可能只是为了不允许创建这个类的实例对象。如果想要创建一个相应的对象,必须重新声明一个实体类,从抽象类继承并实现相应的抽象方法。或者以内部类的方式产生匿名对象。
public class Ex3 {
public static void main(String[] args) {
Sub sub = new Sub();
sub.print();
}
}
abstract class Base {
// 这里摘自http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5
// Unlike C++, the Java programming language does not specify
// altered rules for method dispatch during the creation of a
// new class instance. If methods are invoked that are
// overridden in subclasses in the object being initialized,
// then these overriding methods are used, even before the new
// object is completely initialized.
public Base() {
print();
}
abstract void print();
}
class Sub extends Base {
int i = 7;
@Override
void print() {
System.out.println("i = " + i);
}
}
/*
output:
i = 0
i = 7
前面的0是在父类构造器里面调用子类print方法时候打印的,这时候
实例域全部都初始化默认值,所以打印为0
*/
abstract class Dad {
}
class Son extends Dad {
protected void print() { System.out.println("Son"); }
}
abstract class SecondDad {
abstract protected void print();
}
class SecondSon extends SecondDad {
protected void print() { System.out.println("SecondSon"); }
}
public class Ex4 {
public static void testPrint(Dad d) {
// 没有print方法,需要向下转型
((Son)d).print();
}
public static void secondTestPrint(SecondDad sd) {
// 实现了抽象类父类的接口,动态分配
sd.print();
}
public static void main(String[] args) {
Son s = new Son();
testPrint(s);
SecondSon ss = new SecondSon();
secondTestPrint(ss);
}
}
接口
interface不仅仅是一个极端的抽象类,因为它允许通过创建一个能够被向上转型为多种基类的类型,来实现某种类似于多重继承的变种。
import java.util.Arrays;
class Processor {
public String name() {
return getClass().getName();
}
Object process(Object input) {
return input;
}
}
class Upcase extends Processor {
@Override
String process(Object input) {
return ((String)input).toUpperCase();
}
}
class Splitter extends Processor {
@Override
Object process(Object input) {
return Arrays.toString(((String)input).split(" "));
}
}
public class Apply {
public static String name = "Disagreement with beliefs is by definition incorrect";
// 创建一个能够根据所传递的参数对象的不同而具有不同行为
// 的方法,被称为策略模式方法包括了将要执行的算法的固定
// 部分,而策略则包含了变化的部分。这里的策略是传递进去
// 的参数对象,包含了将要执行的代码。
public static void process(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}
public static void main(String[] args) {
process(new Upcase(), name);
process(new Processor(), name);
process(new Splitter(), name);
}
}
public class Ex11 {
public static void main(String[] args) {
Apply.process(new StringExAdapter(new StringExchange()), "hazhangfuyqol");
}
}
interface Processor {
String name() {}
Object process(Object input) {}
}
// 这里的类没有实现Processor,所以需要适配器进行转接
class StringExchange {
public String name() {
return getClass().getName();
}
public static String process(String s) {
int length = s.length();
if (length <= 1) return s;
String[] strings = s.split("");
for (int i = 0; i < length - 1; i += 2) {
String tmp = strings[i];
strings[i] = strings[i + 1];
strings[i + 1] = tmp;
}
return String.join("", strings);
}
}
// 适配器,这里的Processor是一个接口
// 这里实际上还应用到了代理模式
class StringExAdapter implements Processor {
private StringExchange se;
public StringExAdapter(StringExchange se) {
this.se = se;
}
@Override
public String name() {
return se.name();
}
@Override
public Object process(Object o) {
return se.process((String)o);
}
}
/*
Using Processor interfaces.filter.StringExchange
ahhznafgyuoql
*/