[Java]多态和接口

1. 多态

将一个方法调用同一个方法主体关联起来被称作绑定。若在程序执行前进行绑定,叫做前期绑定,比如C只有一种方法调用,就是前期绑定。而运行时根据对象的类型进行绑定,叫后期绑定。后期绑定也称做动态绑定或运行时绑定。Java中除了static方法和final方法之外,其他所有的方法都是后期绑定,这意味着它会自动发生,例如:

class Shape { void draw() { } void erase() { }}class Circle extends Shape { void draw() { }}class Square extends Shape { void draw() { }}public class Main { public static void main(String[] args) {Shape s = new Circle();s.draw(); }}

这里创建了一个Circle对象,并把得到的引用赋值给Shape,这是可以的,因为通过继承,Circle就是一种Shape。这时调用方法draw(),由于后期绑定(多态),还是正确调用了Circle.draw()方法。只有非private方法才可以被覆盖,因为private方法被自动认为是final方法,而且对导出类是屏蔽的,例如:

public class Shape { private void draw() {System.out.println(“private”); } public static void main(String[] args) {Shape s = new Circle();s.draw(); // private }}class Circle extends Shape { public void draw() {System.out.println(“public”); }}

只有普通的方法调用是可以是多态的,,如果直接访问某个域,这个访问将在编译期进行解析,例如:

class Super { public int field = 0; public void getField() {System.out.println(field); }}class Sub extends Super { public int field = 1; public void getField() {System.out.println(field); } public void getSuperField() {System.out.println(super.field); }}public class Main { public static void main(String[] args) {Super sup = new Sub();System.out.println(sup.field); // 0sup.getField(); // 1Sub sub = new Sub();System.out.println(sub.field); // 1sub.getField(); // 1sub.getSuperField(); // 0 }}

2. 抽象

Java提供了一个叫做抽象方法的机制,仅有声明而没有方法体,采用的语法如下:

abstract void f();

包含抽象方法的类叫抽象类,如果一个类包含一个或多个抽象方法,类必须被限定为抽象的。如果从一个抽象类继承,并想创建该类的对象,那么就必须为基类中的所有抽象方法提供方法定义,否则导出类也是抽象类,且编译器会强制要求用abstract关键字来限定这个类,例如:

abstract class Test1 { public abstract void f(); public void print() {System.out.println(“Hello World!”); }}class Test2 extends Test1 { public void f() {System.out.println(“Description”); }}public class Main { public static void main(String[] args) {Test2 t = new Test2();t.print();t.f(); }}

3. 接口

interface关键字使抽象的概念更向前迈进了一步,abstract关键字允许在类中创建一个或多个没有任何定义的方法,interface关键字产生一个完全抽象的类,它没有任何相应的具体实现,它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。

要想创建一个接口,需要用interface关键字来替代class关键字,可以在interface关键字前添加public关键字,如果不添加public关键字,则它只具有包访问权限。接口也可以包含域,但是这些域隐式地是static和final的。要让一个类遵循某个特定接口,需要使用implements关键字,除此之外,看起来很像继承。可以选择在接口中显式地将方法声明为public的,但即使不这么做,它们也是public的,因此当要实现一个接口时,在接口中被定义的方法必须被定义为public,例如:

interface Test1 { public void f();}class Test2 implements Test1 { public void f() {System.out.println(“Hello World!”); }}public class Main { public static void main(String[] args) {Test2 t = new Test2();t.f(); }}

4. 多重继承

在C++中,组合多个类的接口的行为被称作多重继承,它可能会带来沉重的包袱,因为每个类都有一个具体实现,在Java中,可以执行相同的行为,但是只有一个类可以有具体实现。在导出类中,不强制要求必须有一个是抽象的或没有任何抽象方法的基类,如果要从一个非接口的类继承,那么只能从一个类去继承,其余的基元素都必须是接口。需要将所有的接口名都置于implements关键字之后,用逗号将它们一一隔开,例如:

interface CanFight { void fight();}interface CanSwim { void swim();}interface CanFly { void fly();}class ActionCharacter { public void fight() {}}class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly { public void swim() {} public void fly() {}}public class Main { public static void main(String[] args) {Hero h = new Hero();h.fight();h.swim();h.fly(); }}

5. 嵌套接口

接口可以嵌套在类或其他接口中,例如:

class Test { interface I {void f(); } public class A implements I {public void f() {} } public class B implements I {public void f() {} }}

在类中嵌套接口的语法就像非嵌套接口一样,可以拥有public和包访问两种可视性,另外作为一种新添加的方式,接口也可以被实现为private(相同的语法即适用于嵌套接口,也适用于嵌套类)。

本文出自 “方圆之间” 博客,谢绝转载!

就微笑着同清风合力染绿大地,这样才算善待生命,不负年华。

[Java]多态和接口

相关文章:

你感兴趣的文章:

标签云: