不是说没有抽象方法的抽象类是没有意义的么? 为什么我还是经常看到一些项目中的一些基类都是定义为了抽象类,并且其中没有一个抽象方法?
为了指针类型安全
指针类型安全? 能简单介绍下?
@清华大学副院长: 你把 php 中使用没有抽象方法的抽象类的代码给贴出来
@Launcher: abstract class Api extends Schema {} 这个类中就没有抽象方法,里面有很多普通方法,就不贴出来了。
@清华大学副院长: 我要看的是使用 Api 的代码。
@Launcher: 有很多类都继承了Api这个类,比如说class Xiangmu extends Api {}这个类 ,这个类中就是对ajax的请求进行处理,然后返回结果。
@清华大学副院长: 我想看到的是利用继承实现多态的代码实例。
@Launcher: 子类中没有实现多态的方法。php中实现多态不就是使用给参数赋默认值的方法么。
@Launcher: 我的意思是子类中没有用到父类中的方法来实现多太
@清华大学副院长: 这样:
class A;
class B : A;
class C : B;
void calc(A *p);
B *p1 = new B;
C *p2 = new C;
calc(p1);
calc(p2);
PHP 中没法这样?
@Launcher: 我不知道你这是啥语言,不太看得懂,不过大概看了下,好像就是B继承A,C继承B,A中一个方法,B的对象实例调用A中的方法,C的对象实例调用A中的方法?这貌似不就是继承么?
@清华大学副院长:
class A;
class B : A;
class C : B;
class D;
void calc(A *p);
B *p1 = new B;
C *p2 = new C;
D *p3 = new D;
calc(p1); // 编译通过,在 PHP 中应该是解释通过
calc(p2); // 编译通过,在 PHP 中应该是解释通过
calc(p3); // 编译不通过,在 PHP 中解释能通过吗?
@Launcher: D没有继承A ,怎么调用A的方法....
@清华大学副院长: PHP 中没有全局函数吗?
class F
{
void calc(A *p);
}
F f;
f.calc(p1);
f.calc(p2);
f.calc(p3);
@Launcher: 有啊,不过兄弟啊,void calc(A *p);这句话我看不懂啊。这是啥语言啊?
@清华大学副院长: 简单浏览了下 PHP 语法,我用 PHP 语法给你演示下继承的作用:
class Myclass
{
public function test(A &$a);
}
class A;
class B extends A;
class C;
$myClass = new MyClass;
$b = new B;
$c = new C;
myClass->test($b);
myClass->test($c);
@Launcher: public function test(A &$a); PHP没有这种写法吧,而且PHP的继承我是知道怎么用的啊,我的问题是抽象类中如果没有抽象方法,那这个类为什么要定义成抽象类?
@清华大学副院长: public function test(A $a); 有这种写法不?
@Launcher: 没有见过,应该没有, test() 方法的参数顶多就是test($a)或者地址传值test(&$a)吧,也是没见过把一个对象的实例传到一个方法中啊...
@Launcher: 涨姿势了,以前没见到过。你讲的意思是A的所有子类实例化出来的对象都是可以传入那个cale()的,不过这也是讲的继承啊....
@Launcher: 不对,你这个好像就是讲的实现下面那位同学讲的通过组合来实现继承吧....
@清华大学副院长: 这叫着多态。http://blog.csdn.net/ruyue_ruyue/article/details/8211809
@Launcher: 这好像与我的问题关系也不大吧....
@清华大学副院长: 大啊,public function test(A $a) 限定输入参数类型必须是 A,那么 A 及 A 的派生类的实例都可以使用,如果按照你的 A 没必要存在了,那么把 A 去了。为了实现这个功能,我是不是要写:
public function test(B $b);
public function test(C $c);
public function test(D $d);
三个方法来把相同的代码 COPY 三次。
谁说,没有抽象方法的抽象类是没有意义的?没有抽象方法的抽象类多了
没有抽象方法的类我就可以没有必要定义成抽象类了,普通的类不就可以实现继承了么?既然他定义成了抽象类,就一定有他的作用,现在的问题就是,有什么作用?
@清华大学副院长: 我要是想让一个类不能被实例化,只能被继承呢.这不就是意义?
这种事情是没有意义的,弄清楚语法上的定义就可以了.怎么用还是看情况..
我碰到过的抽象类中没有抽象方法,一种可能是重构的时候为了复用基类的一些方法,另一种可能就是抽象做的不好。建议少用类继承,多用组合。
组合是什么?
@清华大学副院长: 互联网时代必须要学会搜索啊。
继承和组合都是实现代码复用和系统功能重用的最常见的设计技巧。
举例,A类和B类,如果是继承,A继承B,那么子类A与父类B之间紧密耦合,子类A依赖于父类B的实现,最直接的副作用是父类B实现的任何变化,而子类A依赖父类的这个实现,必然会导致子类A的改变。
如果是组合,简单做法是在A类中加入一个B类的实例,这样就可以复用B,B的任何改变,对A都是透明的,A不用改动。当然,实际开发过程中最常见的组合,通常都是通过接口,通过IOC技术实现类解耦,具体的实现类之间不会去关心各自的实现细节,即它们之间的实现细节是不可见的。
@JeffWong: 对A是透明的,没有听懂这句话。在A中加入B的实例,然后通过实例调B中的方法,这不一样么?B改变了,A中的实现不也是会影响或是改变
@清华大学副院长: 组合的话,B改变了,A自身没有代码改变。如果是继承,B改变则A也改变。讨论复用的时候,不得不讲依赖,你看看类之间的依赖关系就知道继承和组合的区别了。看来当年学习系统分析和设计还是管用的,你要熟悉一下UML里的几个基础概念。多看多写多思考,相信你会明白的。
@JeffWong: 继承的话,B中的方法改变了,A中调用B的方法,A中代码也是不用变的啊
抽象类 没有抽象方法是为了以下2个目的:
1.为了让当前类不被实例化
2.为了让后面的子类可以继承当前抽象类的方法 免去重写