首页 新闻 会员 周边

抽象类中的抽象方法

0
悬赏园豆:5 [已解决问题] 解决于 2015-06-01 16:39

不是说没有抽象方法的抽象类是没有意义的么? 为什么我还是经常看到一些项目中的一些基类都是定义为了抽象类,并且其中没有一个抽象方法?

php
清华大学副院长的主页 清华大学副院长 | 初学一级 | 园豆:28
提问于:2015-04-29 14:00
< >
分享
最佳答案
1

为了指针类型安全

收获园豆:3
Launcher | 高人七级 |园豆:45045 | 2015-04-29 14:09

指针类型安全?  能简单介绍下?

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:14

@清华大学副院长: 你把 php 中使用没有抽象方法的抽象类的代码给贴出来

Launcher | 园豆:45045 (高人七级) | 2015-04-29 14:15

@Launcher: abstract class Api extends Schema {} 这个类中就没有抽象方法,里面有很多普通方法,就不贴出来了。

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:17

@清华大学副院长: 我要看的是使用 Api 的代码。

Launcher | 园豆:45045 (高人七级) | 2015-04-29 14:23

@Launcher: 有很多类都继承了Api这个类,比如说class Xiangmu extends Api {}这个类 ,这个类中就是对ajax的请求进行处理,然后返回结果。

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:31

@清华大学副院长: 我想看到的是利用继承实现多态的代码实例。

Launcher | 园豆:45045 (高人七级) | 2015-04-29 14:45

@Launcher: 子类中没有实现多态的方法。php中实现多态不就是使用给参数赋默认值的方法么。

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:55

@Launcher: 我的意思是子类中没有用到父类中的方法来实现多太

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:57

@清华大学副院长: 这样:

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 | 园豆:45045 (高人七级) | 2015-04-29 15:03

@Launcher: 我不知道你这是啥语言,不太看得懂,不过大概看了下,好像就是B继承A,C继承B,A中一个方法,B的对象实例调用A中的方法,C的对象实例调用A中的方法?这貌似不就是继承么?

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 15:24

@清华大学副院长: 

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 | 园豆:45045 (高人七级) | 2015-04-29 15:27

@Launcher: D没有继承A ,怎么调用A的方法....

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 15:35

@清华大学副院长: PHP 中没有全局函数吗?

class F

{

   void calc(A *p);
}

F f;

f.calc(p1);

f.calc(p2);

f.calc(p3);

Launcher | 园豆:45045 (高人七级) | 2015-04-29 15:37

@Launcher: 有啊,不过兄弟啊,void calc(A *p);这句话我看不懂啊。这是啥语言啊?

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 15:41

@清华大学副院长: 简单浏览了下 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 | 园豆:45045 (高人七级) | 2015-04-29 15:44

@Launcher: public function test(A &$a); PHP没有这种写法吧,而且PHP的继承我是知道怎么用的啊,我的问题是抽象类中如果没有抽象方法,那这个类为什么要定义成抽象类?

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 15:50

@清华大学副院长: public function test(A $a); 有这种写法不?

Launcher | 园豆:45045 (高人七级) | 2015-04-29 15:57

@Launcher: 没有见过,应该没有, test() 方法的参数顶多就是test($a)或者地址传值test(&$a)吧,也是没见过把一个对象的实例传到一个方法中啊...

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 16:00
Launcher | 园豆:45045 (高人七级) | 2015-04-29 16:05

@Launcher: 涨姿势了,以前没见到过。你讲的意思是A的所有子类实例化出来的对象都是可以传入那个cale()的,不过这也是讲的继承啊....

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 16:16

@Launcher: 不对,你这个好像就是讲的实现下面那位同学讲的通过组合来实现继承吧....

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 16:18

@清华大学副院长: 这叫着多态。http://blog.csdn.net/ruyue_ruyue/article/details/8211809

Launcher | 园豆:45045 (高人七级) | 2015-04-29 16:29

@Launcher: 这好像与我的问题关系也不大吧....

清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 16:38

@清华大学副院长: 大啊,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 三次。

Launcher | 园豆:45045 (高人七级) | 2015-04-29 16:45
其他回答(3)
0

谁说,没有抽象方法的抽象类是没有意义的?没有抽象方法的抽象类多了

收获园豆:1
吴瑞祥 | 园豆:29449 (高人七级) | 2015-04-29 14:19

没有抽象方法的类我就可以没有必要定义成抽象类了,普通的类不就可以实现继承了么?既然他定义成了抽象类,就一定有他的作用,现在的问题就是,有什么作用?

支持(0) 反对(0) 清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:28

@清华大学副院长: 我要是想让一个类不能被实例化,只能被继承呢.这不就是意义?

这种事情是没有意义的,弄清楚语法上的定义就可以了.怎么用还是看情况..

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2015-04-29 14:30
0

我碰到过的抽象类中没有抽象方法,一种可能是重构的时候为了复用基类的一些方法,另一种可能就是抽象做的不好。建议少用类继承,多用组合。

收获园豆:1
JeffWong | 园豆:2328 (老鸟四级) | 2015-04-29 14:32

组合是什么?

支持(0) 反对(0) 清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 14:38

@清华大学副院长: 互联网时代必须要学会搜索啊。

继承和组合都是实现代码复用和系统功能重用的最常见的设计技巧。
举例,A类和B类,如果是继承,A继承B,那么子类A与父类B之间紧密耦合,子类A依赖于父类B的实现,最直接的副作用是父类B实现的任何变化,而子类A依赖父类的这个实现,必然会导致子类A的改变。
如果是组合,简单做法是在A类中加入一个B类的实例,这样就可以复用B,B的任何改变,对A都是透明的,A不用改动。当然,实际开发过程中最常见的组合,通常都是通过接口,通过IOC技术实现类解耦,具体的实现类之间不会去关心各自的实现细节,即它们之间的实现细节是不可见的。

支持(0) 反对(0) JeffWong | 园豆:2328 (老鸟四级) | 2015-04-29 15:08

@JeffWong: 对A是透明的,没有听懂这句话。在A中加入B的实例,然后通过实例调B中的方法,这不一样么?B改变了,A中的实现不也是会影响或是改变

支持(0) 反对(0) 清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 15:32

@清华大学副院长: 组合的话,B改变了,A自身没有代码改变。如果是继承,B改变则A也改变。讨论复用的时候,不得不讲依赖,你看看类之间的依赖关系就知道继承和组合的区别了。看来当年学习系统分析和设计还是管用的,你要熟悉一下UML里的几个基础概念。多看多写多思考,相信你会明白的。

支持(0) 反对(0) JeffWong | 园豆:2328 (老鸟四级) | 2015-04-29 15:48

@JeffWong: 继承的话,B中的方法改变了,A中调用B的方法,A中代码也是不用变的啊

支持(0) 反对(0) 清华大学副院长 | 园豆:28 (初学一级) | 2015-04-29 16:05
0

抽象类 没有抽象方法是为了以下2个目的:

1.为了让当前类不被实例化

2.为了让后面的子类可以继承当前抽象类的方法 免去重写

小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2015-04-29 16:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册