第3章 Java与面向对象——FAQ3.03 什么是抽象类?有什么好处?
FAQ3.03 什么是抽象类?有什么好处?
答:
抽象类是包含一种或多种抽象方法的类,它本身不需要构造实例。
定义抽象类后,其它类可以对它进行扩充,并且通过实现其中的抽象方法,使抽象类具体化。
————————————————————————————————————————————————————————————————————————————————————————
在类中含有abstract的方法,则该类就是抽象类。你不能new一个抽象类,即不能实例化一个抽象类。
一般来说建议能把抽象类中的非abstract方法排除掉,把它变为接口。。。
————————————————————————————————————————————————————————————————————————————————————————
普通类可以创间对象,
抽象类不可以,
普通类可以继承抽象类,且必须实现抽象类的方法。
————————————————————————————————————————————————————————————————————————————————————————
抽象类A
普通类B,C。都是从A继承出来的。
A中有abstract方法f1,f2,f3....,这些方法在B,C中才实现。
这样,对于任何一个B,C的实例,我们都可以把他当作A来使用。
而且可以访问这些在B,C中实现的方法。
————————————————————————————————————————————————————————————————————————————————————————
抽象类里面可以没有一个抽象方法的。
抽象类和继承他的子类之间的关系是子类 是 抽象类
现实生活中猪是一种动物 ,鸡也是动物
我们在OO中把动物设计为一个抽象类 ,而猪和鸡继承动物。
动物这个类里面比如行走是一个抽象方法。
就是说动物的行走是不一样的。
鸡是两只脚走主是四只脚走。所以在动物的类里面是实现不了这个方法。
只能继承他的类去实现。
不知道这样说你是否明白。
————————————————————————————————————————————————————————————————————————————————————————
抽象类可以让你实现同态性啊 很方便的啊
比如抽象类定义一个方法,其各个子类实现这个方法的细节可以不一样
而一个抽象类变量可以实例化为其各个子类的实例,这样你调用该方法时形式相同!实现的细节由子类的实例自己处理!
————————————————————————————————————————————————————————————————————————————————————————
抽象类,可以说是实现的一种模板功能!
其他的类在此模板的基础上可以扩充,多个类在基本功能一样的前提下,可以通过实现一个“模板”----抽象类来完成!
————————————————————————————————————————————————————————————————————————————————————————
抽象类即是不能被实例化的类,而且你不能够在自己的程序里通过这种类来生成一个对象。
你也许会认为不能被实例化的类是没多大用处的。事实上,在某些环境下, 抽象类是非常有用的。你可以把它作为一个基础类以此为基类创建新的类。 在对功能要求不高的环境下生成的类,会向你提供一个规定的启始点,通过这个点你可以推导出非抽象类。
在此假设一个要用抽象类的程序设计。假设图形程序提供了大量的drawing类:比如圆,三角,曲线等等。所有这些作drawing类都有某个共同的特性,比如位置,大小,色彩,删除等属性。其它的类成员,比如描绘图形的方法就不同于每个单独的类。因此,这样为利用抽象类创造了一个理想的环境
————————————————————————————————————————————————————————————————————————————————————————
接口就是更纯粹的抽象类
————————————————————————————————————————————————————————————————————————————————————————
首先,我们来看一下抽象类的概念,java编程思想中说“万物皆对象”,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类是表征我们对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。好比,我们都知道三角形是一个形状,世界上有三角形这样具体的东西,但是确没有形状这样具体的东西,我们要描述这个形状的概念就要用到抽象类。因此在java中抽象类是不允许被实例化的。
在面向对象领域,抽象类主要用来进行类型隐藏。那什么是类型隐藏呢?我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。好比,动物是一个抽象类,人、猴子、老虎就是具体实现的派生类,我们就可以用动物类型来隐藏人、猴子和老虎的类型。
再来看一下接口,接口是什么呢?Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口是一种特殊形式的抽象类。
抽象类和接口有很大的区别,首先,抽象类在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个接口。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。
其次,在抽象类的定义中,我们可以赋予方法的默认行为。但是在接口的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会 增加一些复杂性,有时会造成很大的麻烦。
已经提到过,抽象类在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在”is a”关系,即父类和派生类在概念本质上应该是相同的。对于接口来说则不然,并不要求接口的实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已。接口表示的是”like a”关系。
使用抽象类来定义允许多个实现的类型,比使用接口有一个明显的优势:抽象类的演化比接口的演化要容易的多。在后续的发行版中,如果希望在抽象类中增加一个方法,只增加一个默认的合理的实现即可,抽象类的所有实现都自动提供了这个新的方法。对于接口,这是行不通的。虽然可以在骨架实现类中增加一方法的实现来解决部分问题,但这不能解决不从骨架实现类继承的接口实现的问题。由此,设计公有的接口要非常谨慎,一旦一个接口被公开且被广泛实现,对它进行修改将是不可能的。
所以,使用接口还是抽象类,取决于我们对问题的概念的本质理解和设计的意图。