`

【Java】浅析final,abstract修饰符

    博客分类:
  • Java
阅读更多

 

有时候,你不希望别人坐享其成,通过继承你写的类得到他自己所需要的类,怎么办呢?这个时候你就可以在你的class之前加上final这个修饰府,例如public final class test{……},加上了这个修饰符之后,别人在继承这个类的话就会编译出错,提示他这个类不能构建子类。从这我们可以看出,final修饰符和abstract修饰符是不能同时使用的,因为abstract类可以说是专门用来继承的,而final类则不能用于继承。那么如果是在方法的前面加上final修饰符有什么作用呢?比如说A类中有个声明为final的方法a(){….},那么B继承A的时候,B就不能覆盖方法a(){….},否则编译出错,提示Cannot override the final method from A。此外,如果一个类声明为final类的话,它里面所有的方法都自动成为final类型的。自然的,你肯定会问,如果一个域申明为final的时候有什么作用?一个属性声明为final之后,你不能在对它重新进行赋值,否则编译报错,The final field ×× cannot be assigned。另外,请注意,类声明为final的时候,仅仅它的方法自动变为final,而属性则不会。

2
.抽象类

抽象类的用处是十分大的,特别是对于OOP而言,关于抽象类,总结几点:
a
抽象类不能实例化,即不能对其用new运算符;
b
类中如果有一个或多个abstract方法,则该类必须声明为abstract
c
抽象类中的方法不一定都是abstract方法,它还可以包含一个或者多个具体的方法;
d
即使一个类中不含抽象方法,它也可以声明为抽象类;

 

abstract修饰符
      Abstract
修饰符表示所修饰的类没有完全实现,还不能实例化。如果在类的方法声明中使用abstract修饰符,表明该方法是一个抽象方法,它需要在子类实现。如果一个类包含抽象函数,则这个类也是抽象类,必须使用abstract修饰符,并且不能实例化。

    
在下面的情况下,类必须是抽象类:

     1.
类中包含一个明确声明的抽象方法;

     2.
类的任何一个父类包含一个没有实现的抽象方法;

     3.
类的直接父接口声明或者继承了一个抽象方法,并且该类没有声明或者实现该抽象方法。

    
如下例所示:

     abstract class a1
     {
         public int v1;
         abstract void test();
     }
     abstract class a2 extends a1 
     {
         public int v2;
     }
     class Sample extends v2 
     {
         void test() { }
     }
    
因为包含一个抽象方法test,v1必须被声明为抽象类。它的子类v2继承了抽象方法test,但没有实现它,所以它也必须声明为抽象类。然而,v2的子类Sample因为实现了test,所以它不必声明为抽象的。

    
注意:

    
如果试图创建一个抽象类的实例就会产生编译错误;

    
如果一个类是非抽象类却包含一个抽象方法,就会产生编译错误;

    
构造函数和静态函数以及Final修饰的函数不能使用abstract修饰符;

     
接口缺省为abstract

 

Static修饰符
      通常,在创建类的实例时,每个实例都会创建自己实例变量。但是在变量的声明中可以使用Static修饰符,它表明该成员变量属于类本身,独立于类产生的任何对象。这种成员变量称为静态变量(静态属性)。方法的声明中也可以使用static修饰符,表明该方法从属于类本身。

    
在静态成员函数中只能直接调用其它的静态成员函数或引用静态属性,否则会造成编译错误。静态成员函数中也不能使用this或者super,因为它们是和类的对象相关联的。

    
静态属性和静态方法不需要创建实例就可以使用。

    
典型的例子是java.lang包中的System类中的方法和变量。我们常用

     System.out.println(“message”);

    
输出信息,并没有创建System的实例,是因为println方法声明为System类的静态方法,它不需创建实例就可以使用。

    
下面的例子会帮助你更深刻的理解Static修饰符。注意各个代码块的加载次序。



     Class Sample
     {
         static int s1=3;
         static int s2;
         static void display() 
         {
             System.out.println("s1="+s1);
             System.out.println("s2="+s2);
         }
         static
         {
             System.out.println("static block");
             S2=s1+1;
         }
         public static void main(Stringargs[])
         {
             Sample.display();
         }
     }

    
一旦这个类被调用,所有的静态变量都被初始化,s1被赋为3,然后运行static块,这将打印出一段消息,并且把s2赋为s1+1,即4。然后解释器调用main成员函数,它调用了成员函数display,该函数输出s1s2的信息。运行结果如下:

     C:\>java Sample
     static block
     s1=3
     s2=4
    
通过上面的例子还可以看出,一个静态成员函数可以通过它所属的类名来调用。

final修饰符
      
如果一个类是完全实现的,并且不再需要继承子类,则它可以声明为Final类。如果final类的名字出现在另一个类声明的extends字句的后面就会产生编译错误。这表明final类不能又任何的子类。类不能同时被声明为abstractfinal,因为abstract类中的abstract方法永远没有机会被实现。

     
在缺省情况下,所有的成员函数和实例变量都可以被覆盖。如果你希望你的变量或成员函数不再被子类覆盖,可以把它们声明为final

    
例如:

     final int MAX_VALUE = 100; 

    
表示,MAX_VALUE的值为100,并且不能再更改。final变量用大写标识符是一个一般的约定。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics