java - 抽象类、接口、内部类

做者:eggjava

微博:http://weibo.com/xtfggef编程

出处:http://blog.csdn.net/zhangerqingide

 

抽象类与接口:ui

这两个概念老是被放在一块儿讨论,由于他们有不少类似的地方,能够说接口自己就是彻底抽象的,它要比抽象类更加“抽象”,为何这么说?抽象类是一种类,里面除了有抽象方法外,还能够有具体的方法,而接口里面必须都是抽象的方法(有时能够在接口里定义类,后面会讲),尽管有时并无显示的用abstract关键字声明。此处咱们提到抽象方法,在Java中,凡是声明为形如:abstract void function()的方法,都是抽象方法,包含抽象方法的类就是抽象类,能够这么总结:抽象类中是能够没有抽象方法的;有抽象方法的类必须是抽象类;抽象类不必定有实体方法。this

public class Run {.net

    public Runnable run22() {
        return new Runnable() {
            public void run() {
                System.out.println("run~~");
            }
        };
    }设计

    public static void main(String[] args) {
        new Run().run22().run();
    }
}
 htm

  1. public class B extends A {  
  2.   
  3.     @Override  
  4.     void a() {  
  5.         System.out.println();  
  6.     }  
  7.   
  8. }  
  9. abstract class A {  
  10.   
  11.     abstract void a();  
  12.     void b(){  
  13.           
  14.     }  
  15. }  

当咱们继承抽象类时,必须重写其抽象方法。由于上述缘由,因此抽象类不能被声明为final类型的,由于加final关键字的类保证不能被继承,所以为抽象类加final关键字,这个类就无法用了。抽象类只能被继承,不能被实例化!对象

 

 

声明为interface的类为接口,比抽象类更加抽象的一种机制。在接口中,咱们不能提供任何实现,全部方法必须都是抽象的,能够不加abstract关键字,可是编译器对于接口中的方法,都是直接按抽象方法处理的。咱们经过implements来实现某个接口。当咱们实现某个接口时,必须重写其全部方法。blog

 

Java多继承

以前咱们知道,采用interface为咱们提供了一种将抽象与实现分离的结构化的方法,可是interface的做用远不止此,在Java中接口解决了一个很是重要的问题:多继承。在C++中,实现多重继承是比较简单的事儿,可是Java继承机制不容许多重继承,因此若是想要整合不一样类的功能,就须要使用接口,咱们来看个例子:

  1. interface CanFight {void fight();}  
  2. interface CanFly {void fly();}  
  3. interface CanSwim {void swim();}  
  4. class ActionCharacter {public void fight(){}}  
  5. class Hero extends ActionCharacter implements CanFight, CanFly, CanSwim {  
  6.   
  7.     @Override  
  8.     public void swim() {}  
  9.   
  10.     @Override  
  11.     public void fly() { }  
  12.   
  13. }  
  14. public class Adventure {  
  15.       
  16.     public static void t(CanFight x){x.fight();}  
  17.       
  18.     public static void u(CanSwim x){x.swim();}  
  19.       
  20.     public static void v(CanFly x){x.fly();}  
  21.       
  22.     public static void w(ActionCharacter x){x.fight();}  
  23.       
  24.     public static void main(String[] args) {  
  25.         Hero h = new Hero();  
  26.         t(h);  
  27.         u(h);  
  28.         v(h);  
  29.         w(h);  
  30.     }  
  31. }  

咱们能够看到:

一、Hero类中拥有了全部类的功能。

二、Hero能够和它实现的这些接口进行相互转换,当咱们将hero对象作参数,传入Adventure类的各个方法时,Hero类向上转型了。(此处咱们得出了一句话:在Java中,接口能够和实现了该接口的类相互转换)。讲到此处,我想总结下使用接口的好处:

一、接口能够实现向上转型,多个具备共同属性的类能够将它们的共同点提取出来,作成抽象,这样井井有条,统一管理。

二、接口不具备任何实现,最适合作基类。

总结一下抽象类与接口的区别和联系:

a)  抽象类是类,能够有实体方法。

b)  抽象类不能实现多继承,而接口能够。

c)  若是须要建立不带任何方法定义和成员变量的基类,则使用接口,若是类中须要有部分具体的实现,则使用抽象类。

d)  若是事先想要将某类设计为一个基类,那么首选接口。(注意c和d是接口的使用场景

接口能够经过继承(extends)接口,来拓展功能。接口中的域默认是final、static的,咱们能够经过类名来直接引用。
内部类

 

建立:内部类的意思就是将类的定义放在另外一个类的内部。有时合理的内部类使用会使代码更加简洁,令程序更加巧妙。并且做为外部类的成员,内部类能够访问外部类私有的成员变量。咱们先来看看内部类的建立,分这么几种状况:

一、在外部类的非静态方法中建立内部类的实例。

 

  1. public class InnerClass {  
  2.     class A{  
  3.         int a = 10;  
  4.         void b(){  
  5.             System.out.println("this is A.b()!");  
  6.         }  
  7.     }  
  8.       
  9.     void build(){  
  10.         A a = new A();  
  11.         a.b();  
  12.     }  
  13.       
  14.     public static void main(String[] args) {  
  15.         InnerClass ic = new InnerClass();  
  16.         ic.build();  
  17.     }  
  18. }  

 

 

二、在外部类的静态方法中建立内部类的实例。

当在外部类的静态方法中建立内部类时,当内部类是静态的:

 

  1. public class InnerClass {  
  2.     static class A{  
  3.         int a = 10;  
  4.         void b(){  
  5.             System.out.println("this is A.b()!");  
  6.         }  
  7.     }  
  8.       
  9.     public static void main(String[] args) {  
  10.         InnerClass.build();  
  11.     }  
  12.       
  13.     static void build(){  
  14.         A a = new A();  
  15.         a.b();  
  16.     }  
  17. }  

当内部类是非静态的:

 

  1. public class InnerClass {  
  2.     class A{  
  3.         int a = 10;  
  4.         void b(){  
  5.             System.out.println("this is A.b()!");  
  6.         }  
  7.     }  
  8.       
  9.     public static void main(String[] args) {  
  10.         InnerClass ic = new InnerClass();  
  11.         InnerClass.A aa = ic.new A();  
  12.         aa.b();  
  13.     }  
  14. }  

三、在内部类的非静态方法中建立外部类的实例。(使用外部类.this来建立外部类的实例)

 

  1. public class InnerClass {  
  2.     class A{  
  3.         int a = 10;  
  4.         void build(){  
  5.             InnerClass ic = InnerClass.this;  
  6.             ic.a();  
  7.         }  
  8.     }  
  9.       
  10.     void a(){  
  11.         System.out.println("this is InnerClass.a()!");  
  12.     }  
  13. }  

四、在内部类的静态方法中建立外部类的实例。(直接经过new来建立)

 

  1. public class InnerClass {  
  2.     static class A{  
  3.         int a = 10;  
  4.         static void build(){  
  5.             InnerClass ic = new InnerClass();  
  6.             ic.a();  
  7.         }  
  8.     }  
  9.       
  10.     void a(){  
  11.         System.out.println("this is InnerClass.a()!");  
  12.     }  
  13. }  

五、在其它类中建立内部类实例。(重点)

 

  1. public class InnerClass {  
  2.     class A{  
  3.         void a(){  
  4.             System.out.println("this is A.a()!");  
  5.         }  
  6.     }  
  7.     static class C{  
  8.         void c(){  
  9.             System.out.println("this is C.c()!");  
  10.         }  
  11.     }  
  12. }  
  13. class B{  
  14.     public static void main(String[] args){  
  15.         /*建立非静态内部类*/  
  16.         InnerClass ic = new InnerClass();  
  17.         A a = ic.new A();  
  18.         a.a();  
  19.           
  20.         /*建立静态内部类*/  
  21.         C c = new C();  
  22.         c.c();  
  23.     }  
  24. }  

来看个深层嵌套的:

 

  1. public class ABC {  
  2.     void a() {  
  3.         System.out.println("this is A.a()!");  
  4.     }  
  5.   
  6.     class B {  
  7.         void b() {  
  8.             System.out.println("this is B.b()!");  
  9.         }  
  10.   
  11.         class C {  
  12.             void c() {  
  13.                 a();  
  14.                 b();  
  15.                 System.out.println("this is C.c()!");  
  16.             }  
  17.         }  
  18.     }  
  19.   
  20.     public static void main(String[] args) {  
  21.         ABC abc = new ABC();  
  22.         ABC.B b = abc.new B();  
  23.         ABC.B.C c = b.new C();  
  24.         c.c();  
  25.     }  
  26. }  

感受愈来愈有意思了!此处最重要的就是这个”.new”操做符。同时,在类C内部调用a()和b()都很轻松,就说明内部类就至关于一个普通的变量,哪怕是private权限的,也同样,直接调用,由于它们在同一个类中。匿名内部类的建立:

 

  1. interface A {  
  2.     void a();  
  3. }  
  4.   
  5. public class InnerClass_NoName {  
  6.   
  7.     public A test() {  
  8.         return new A() {  
  9.             public void a() {  
  10.                 System.out.println("");  
  11.             }  
  12.         };  
  13.     }  
  14.   
  15.     public static void main(String[] args) {  
  16.         InnerClass_NoName icn = new InnerClass_NoName();  
  17.         A a = icn.test();  
  18.         a.a();  
  19.     }  
  20. }  

典型的状况是,内部类继承自某个类或实现某个接口,内部类的代码操做建立其的外围类的对象。因此你能够认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的缘由是:每一个内部类都能独立地继承自一个(接口的)实现,因此不管外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。若是没有内部类提供的能够继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。通常状况,内部类不宜过长,不然就会显得头重脚轻。

使用匿名内部类应该注意:

a)        匿名内部类不能有构造方法

b)        匿名内部类不能定义任何静态成员、方法和类。

c)         匿名内部类不能是public,protected,private,static。

d)        只能建立匿名内部类的一个实例。

e)        一个匿名内部类必定是在new的后面,用其隐含实现一个接口或实现一个类。

f)         因匿名内部类为局部内部类,因此局部内部类的全部限制都对其生效。

嵌套类:

普通的内部类持有外围类的一个引用,因此能够与外部类保持联系,而当咱们须要嵌套类的时候,咱们须要使用static关键字,这样内部类就断开了和外部类的联系,不能从内部类的对象中访问非静态的外部类。

 

  1. public class InnerClass {  
  2.       
  3.     static class A{  
  4.         static int a = 10;  
  5.         static void a(){  
  6.             System.out.println("this is A.a()!");  
  7.         }  
  8.     }  
  9. }  

 

 

接口内部的类:

 

  1. public interface Interface_Class {  
  2.     void say();  
  3.     class IC implements Interface_Class{  
  4.         @Override  
  5.         public void say() {  
  6.             System.out.println("hello");  
  7.         }  
  8.         public static void main(String[] args) {  
  9.             new IC().say();  
  10.         }  
  11.     }  
  12. }  

适合于建立公共代码,供全部实现了该接口的类使用。

内部类的继承,咱们说过,内部类持有对外部类的引用,因此,在继承的时候,咱们须要初始化这个“隐藏”着的引用,请看下面的代码:

 

  1. class AAA {  
  2.     class BBB {  
  3.   
  4.     }  
  5. }  
  6.   
  7. public class InnerClass_Extends extends AAA.BBB {  
  8.     public InnerClass_Extends(AAA aaa) {  
  9.         aaa.super();  
  10.     }  
  11.   
  12.     public static void main(String[] args) {  
  13.         AAA aaa = new AAA();  
  14.         InnerClass_Extends ice = new InnerClass_Extends(aaa);  
  15.     }  
  16. }  

最后,咱们总结下使用内部类的缘由:每一个内部类都能独立继承自一个接口的实现,和外部类没有任何关系(不论外部类是否实现了该接口)。

说的再简单一点就是,内部类是Java多继承机制的完美补充,为何这样说?咱们说过,实现多继承靠的是接口,光从类的角度说是没有多继承一说的。可是,若是如今非得用抽象类实现多继承,很明显是不可能的,此处就必须使用内部类。举个例子:

 

  1. class AA{  
  2.       
  3. }  
  4. abstract class BB{  
  5.       
  6. }  
  7. class CC extends AA{  
  8.     BB makeB(){  
  9.         return new BB(){  
  10.               
  11.         };  
  12.     }  
  13. }  
  14. public class Multi_Extends {  
  15.       
  16.     static void takesA(AA a){}  
  17.     static void takesB(BB b){}  
  18.       
  19.     public static void main(String[] args) {  
  20.         CC c = new CC();  
  21.         takesA(c);  
  22.         takesB(c.makeB());  
  23.     }  
  24.   
  25. }  

这样就实现了继承内部类。

相关文章
相关标签/搜索