CSDN博客

img moxifeng

为什么要在定义抽象类时使用abstract关键字

发表于2008/9/30 23:03:00  299人阅读

分类: .NF(CLR-C#)

   众所周之,在任何面向对象的语言中(包括JavaC#),在定义抽象类时必须使用abstract关键字。虽然这已经习已为常了,但实际上abstract是为了在实现接口或继承抽象类避免歧议而必须存在的。

    看如下代码:

abstract class Class1
{
   
abstract void method();
}

    上面的代码是一个典型的抽象类,在定义类时和定义方法时都使用了abstract。但从编译器的角度来说,在定义类时完全可以不使用abstract,如下面的代码所示:


 

class Class1
{
   
abstract void method();
}

    对于上面的代码,编译器在编译时并不会产生奇异,只要检测到类中有一个用abstract关键字的代码,就可以在编译的过程中自动向Class1添加abstract,也就是说,在定义Class1时添加abstract的工作应该由编译器来完成。

    虽然上面的过程看起来没什么问题,也并不难实现,但各位不要忘了,实现抽象类除了上面的方式,还有另外一种方式,这就是实现接口,而并不实现接口中的所有方法。看下面的代码:


 

interface MyInterface
{
    
public void method1();
    
public void method2();
}
abstract class MyClass implements MyInterface
{
    
public void method1()
    {
        
    }
}

    上面代码中MyClass类并未实现method2方法,也并示在定义方法时使用abstract关键字,然后,method2方法实际上就是abstract方法。

   大家可以想象,如果在定义抽象类时不使用abstract关键字会怎么样呢?看下面的代码:


 

interface MyInterface
{
    
public void method1();
    
public void method2();
}
class MyClass implements MyInterface
{
    
public void method1()
    {
        
    }
}

    上面的代码一定会编译出错的,因为编译器蒙了。在面向对象语言中规定,一个普通类必须实现接口中的所有方法。而在上面的代码中,method2方法未实现。而编译器无法判断MyClass类是抽象类,还是普通类。如果按着普通类来处理,则会编译出错,如果按着抽象类来处理,则完全符合面向对象规则。因此,就产生了歧议。当编译器在编译源代码时,一定会产生错误,否则可能会编译成和源代码的含义不同的二进制目标文件。

    当然,上面的代码也可以设置默认的规则,也就是按着普通类处理不通过时,就按着抽象类来处理。但这又会带来另一个问题。如果开发人员忘记实现某个接口的方法,那不是这个类就会被编译器认为是抽象类了吗?因此,为了保险起见,编译器的设计者特意为抽象类指定一个abstract关键字,也就是说,这个类是否是抽象类,应由开发人员通过编码的方式来指定,而不是由编译器自做主张。

    从上面的描述可以看出,加abstract关键字主要是为了避免普通类在实现接口时产生的歧议。如果假设面向对象语言中没有接口,abstract关键字完全可以去掉。当然,继承抽象类也和实现接口类似。

    象面向对象语言中的静态方法很多就没有静态类的概念(Java没有,C#有)。因此,在定义类时加不加static,并不会产生奇异,所以static关键字在定义静态类时也就不是必须的了。

posted on 2008-09-30 14:33 银河使者 阅读(476) 评论(10)  编辑 收藏 所属分类: C# 原创

评论

#1楼  2008-09-30 15:13 子逸      

为什么要在定义抽象类时使用abstract关键字 ???
-------------------------------------------
这题起的: 为什么接口定义要用 interface?
为什么整型定义要用 int?
噢, 卖羔的~~~   回复  引用  查看    

#2楼  2008-09-30 15:49 amingo      

为什么吃饭要买米?   回复  引用  查看    

#3楼 [楼主] 2008-09-30 17:24 银河使者      

那为什么定义静态方法不在类前面加static呢?   回复  引用  查看    

#4楼 [楼主] 2008-09-30 17:24 银河使者      

abstract和class以及interface不在同一个层次   回复  引用  查看    

#5楼 [楼主] 2008-09-30 17:26 银河使者      

在类前面加abstract是为了解决语义分析的歧议性问题,想想为什么在定义抽象类时只在方法前加abstract为什么不行,而必须要在class前面加abstract。而定义静态方法时只在方法前加static即可。   回复  引用  查看    

#6楼  2008-09-30 17:32 kiler      

晕,抽象类可以不写abstract吗?   回复  引用  查看    

#7楼 [楼主] 2008-09-30 18:43 银河使者      

抽象类必须使用abstract,但加abstract是有原因的,如果抽象类不实现接口,从理论上可以不用abstract关键字来修饰class,但如果抽象类实现接口,则必须使用abstract。 正是由于语言中有接口,所有编译器要求抽象类必须使用abstract,而不单单是在方法前面加abstract。 否则会产生歧议。   回复  引用  查看    

#8楼  2008-09-30 20:45 xinxin1977 [未注册用户]

赶紧转到新手区,小心被拍死   回复  引用    

#9楼 [楼主] 2008-09-30 21:10 银河使者      

现在研究编译原理,本想将abstract关键字去了,但经过考虑,还是不能去,加abstract关键字是有道理地。哈哈!难道各位没想过这个问题??   回复  引用  查看    

#10楼 [楼主] 2008-09-30 21:20 银河使者      

谁都知道在定义抽象类时要在抽象方法和类前都加abstract,但类前面为什么必须加一个abstract关键字呢?而在定义静态方法时,为什么不必须在类前面加个static呢?编译器的设计者为什么会这样设计语法,为什么不把抽象类前面的abstract关键字去了?这样启不是语法更简捷!! 任何结果都是有原因地,本文就是阐述了这个原因(也许只是原因之一)。
本文并不是讨论抽象类加不加abstract,而是讨论这样设计语法的原因,各位不要误会。每个人都知道苹果熟了要自己落下来,但只有牛顿一人问了为什么。万有引力就这么被发现了。哈哈!   回复  引用  查看    

阅读全文
0 0

相关文章推荐

img
取 消
img