由于C++支持多重继承,所以很容易实现:骡子(公驴和母马杂交的无繁殖能力的后代),
不知道在JAVA中如何实现,不要只口头上说行,写个代码看看,有人说用接口,没想明白怎么写。
不知道在JAVA中如何实现,不要只口头上说行,写个代码看看,有人说用接口,没想明白怎么写。
解决方案 »
- JTextArea内容保存到Txt文件,换行问题。
- JTextArea中如何用setText()方法将日期(date对象)写入记事本中?
- 关于克隆的一个小问题
- public class a和class a
- 紧急求助:关于CommonsNet包,为什么调用FTPFile.setTimestamp()不能修改服务器端的文件上次修改时间啊?
- TOMCAT的问题,高手帮忙看一下
- [新手问题]怎么得到JTextField中用户输入的字符串?
- [求助]请问如何使用jbuilder7中的断点设置,如何最高效率的跟读程序???
- 请问如何用APPLET制作一个可以两人对战的游戏呀?(高分求教!顶也给分!)
- 我想调用图片的单击事件,再用函数动态加载图片,这样为什么不能实现???
- 怎样才算是一个合格的java工程师,感觉自己做了一年的程序员,还停留在增删改查的阶段,就知道几个字符串,集合,JDBC等几个有限的类的用
- jsp中include指令怎样使用
}
class 公驴{
}
class 马{
}
class 公马 extends 马{
}
class 母马 extends 马{
public 马 交配(公马 gm){}
public 骡子 交配(公驴 gl){}
}
}
abstract class 驴{
}
class 公驴 extends 驴{
}
class 母驴 extends 驴{
public 驴 交配(公驴 gl){}
public 骡子 交配(公驴 gm){}
}
abstract class 马{
}
class 公马 extends 马{
}
class 母马 extends 马{
public 马 交配(公马 gm){}
public 骡子 交配(公驴 gl){}
}
第二位:骡子是在马与驴出生后才来的,你一上来就来了一个 class 骡子
第三位:我不理解extends,但你写得应该不是正确的。
骡子 is 马
骡子 is 驴
你会同意吗?继承就是is,比如
母驴 is 驴
人 is 动物
有这种is关系的才有继承关系!不是我思考有问题,而是你根本没理解继承!
class CMammal
{
public:
virtual void Born() = 0;
};// 公驴类
class CMaleDonkey : public CMammal
{
public:
CMaleDonkey() { cout << "Male Donkey Construction\n"; }
virtual void Born() { cout << "Male Donkey Born\n"; }
};// 母马类
class CFemaleHorse : public CMammal
{
public:
CFemaleHorse() { cout << "Female Horse Construction\n"; }
virtual void Born() { cout << "Female Horse Born\n"; }
};// 驴类
class CMule : public CMaleDonkey, CFemaleHorse
{
public:
CMule() { cout << "Mule Construction\n"; }
virtual void Born() { cout << "Mule Born\n"; }
};// 测试程序
int main()
{
CMule *pMule = new CMule;
pMule->Born(); return 0;
}===========================
程序结果:
Male Donkey Construction
Female Horse Construction
Mule Construction
Mule Born
===========================
但是你举的例子不符合多重继承的条件.支持hbwhwang(我是catmiw的马甲) 的说法
但是骡子总和马与驴有点关系的吧,怎么用java表达这种关系呢?我想lz想问的是这个。不能用is a
那就 has a 吧
class 铅笔 {
写() { ... }
}class 橡皮 {
擦() { ... }
}class 带橡皮的铅笔 : 铅笔, 橡皮 {
// 这里不用写任何代码,本类的实例对象已经拥有了“写”和“擦”的功能
}调用代码:
带橡皮的铅笔 tool = new 带橡皮的铅笔();
tool.写();
tool.擦();
interface 书写工具 {
写();
}interface 擦拭工具 {
擦();
}class 铅笔 implements 书写工具 {
写() { ... }
}class 橡皮 implements 擦拭工具 {
擦() { ... }
}class 带橡皮的铅笔_A implements 书写工具, 擦拭工具 {
// 本类必须自己用代码实现“写”和“擦”的功能
// 当然,实现的时候可以委托代理到“铅笔”和“橡皮”类里面去
书写工具 writer = new 铅笔();
擦拭工具 eraser = new 橡皮();
写() { writer.写(); }
擦() { eraser.写(); }
}class 带橡皮的铅笔_B extends 铅笔 implements 擦拭工具 {
// 本类已经具有了“写”的功能,但必须自己用代码实现“擦”的功能
擦拭工具 eraser = new 橡皮();
擦() { eraser.写(); }
}调用代码:
带橡皮的铅笔_A tool_A = new 带橡皮的铅笔_A();
tool_A.写();
tool_A.擦();
带橡皮的铅笔_B tool_B = new 带橡皮的铅笔_B();
tool_B.写();
tool_B.擦();
abstract class CMammal {
public abstract void Born();
};
// 公驴类
class CMaleDonkey extends CMammal {
public CMaleDonkey() {
System.out.print("Male Donkey Construction\n");
} public void Born() {
System.out.print("Male Donkey Born\n");
}
}
// 母马类
class CFemaleHorse extends CMammal {
public CFemaleHorse() {
System.out.print("Female Horse Construction\n");
} public void Born() {
System.out.print("Female Horse Born\n");
}
};
public class CMule {
private CFemaleHorse horse=new CFemaleHorse(); //母马的基因
private CMaleDonkey donkey=new CMaleDonkey(); //公驴的基因
public CMule() {
System.out.print("Mule Construction\n");
}
public void Born() {
System.out.print("Mule Born\n");
} public static void main(String[] args) {
CMule cmule = new CMule();
cmule.Born();
}
}===========================
程序结果:
Male Donkey Construction
Female Horse Construction
Mule Construction
Mule Born
===========================
别这样写啊!写了就漏馅了 (^-^)healer_kx(甘草(我很看好你哦~~~)) :
兄弟高抬了。我倒是很佩服兄弟你,基础扎实了得!
class C公驴interface I母马
class C母马1,class 骡子 implements I公驴, I母马2,class 骡子 extends C公驴 implements I母马3,class 骡子 extends C母马 implements I公驴
但是骡子总和马与驴有点关系的吧,怎么用java表达这种关系呢?我想lz想问的是这个。不能用is a
那就 has a 吧想想你是怎么来的?
你既然是你,既不是你爸,也不是你妈,不能用继承。
但是你总和你爸你妈有点关系的吧,怎么用java表达这种关系呢?
...
...
你的例子很好,但不恰当。
你的例子是通过包容对象来实现的,没有体现出接口继承。
计算机只能对现实有一个近似模拟
任何一种语言对这种模拟的支持程度和方法都不一样
你不能强求它对现实的近似程度,更不能要求每种语言都一样
===========
计算机是用来帮助我们解决现实中的问题的
而不是用来仿真这个世界的
===========另外说句你可能不爱听的话:
既然你是来问问题,就没必要用那种教训人的语气对那些热心帮助你的人说话!
对你的那句话:既然你是来问问题,就没必要用那种教训人的语气对那些热心帮助你的人说话!我欣然接受,我说声对不起。不过这个确实是个现实问题,有个JAVA爱好者对我说,JAVA太好了,什么都很容易实现,有什么包,C++怎么怎么的不行,过时了,结果我就想到了这个问题,让他帮忙模似一下,结果小伙子傻眼了。再次说声对不起,不过还是发现了很多人对对象的包含与继承没搞清楚,你也不要说骡子跟马和驴没有继承关系。那样就说明在此发贴的每个人跟父母没有继承关系。
但是public继承和java extends是不合适的.虽然可能解决部分问题.
非常高兴你能接收我的意见!这样大家就可以平心静气探讨问题了谈谈我理解的继承
---------------------
其实在现实中,严格意义上的“继承”都是在泛的群体上谈共性时才提到的。
继承在个体上根本体现不出来,你说人都是从父母继承了,但是我问你:继承了什么?长得象?那为什么鼻子象父亲,嘴巴象母亲呢?在面向对象的教学里,一直有个误区,就是太强调“继承”了,基本上一上来就是“继承”。“继承”的确很好理解,因此很多学生一学完“继承”,就自以为具备了OO的思想。
可是我们在实际的编程中,很少用到继承!我写了这么多OO的代码,用了extends的代码比例很少。因为我知道,一旦extends,就会继承一堆无用的东西。这点倒是可以用父母和子女的说明,其实子女跟父母的交叉点非常少,为了这么少的交叉点就背上一堆无用的东西,显然是不值得的。我经常给学生举一个例子:举重运动员、足球运动员和运动员之间肯定有某种关系,面向对象的书肯定会告诉你--这是“类”的“继承”关系。但是我可以告诉你--不是!这是一个“接口”和“实现”的关系。我们定义一个运动员接口,它有2个方法 “训练”和“比赛”,让举重运动员、足球运动员....来“实现”这个接口,自己定义这2个方法。
为什么我不认为这是“类”的“继承”关系呢?很显然啊,因为在“运动员”中无法定义“训练”和“比赛”的方法!每一种运动员都有自己的特点。JAVA就是这样一种语言,它更倾向于“接口实现”,而不是“继承”。这也是它在对OO的支持上与C++最大的一个区别。
我觉得这样更合理!我相信也有很多人跟我的想法是一致的。你提到的多重继承,的确有应用的场景,但在实际工作中,少之又少。即使JAVA没有支持它,我也没有觉得它不方便(个别时候稍有感觉)
====================再谈谈我理解的组合(你说的包容)
-----------------------
在实际工作中,我们用“组合”的场合要远多于“继承”,不知道我这个人是不是天生对“继承”不敏感,反正很多很用“继承”的地方我都不用,而是用“组合”。
WHY?我认为组合给了我更多的灵活性!
给你举个例子:
class B extends A
一旦我这么写,那么就把B捆死在A上了。
现在假设A是针对Oracle的实现代码,现在我要做MYSQL的版本了(当然也要保持ORACLE的支持),你说我该怎么办???
因此在实际工作中,我往往是这么做的:
定义一个接口: I,定义一个实现A
而在我的B中:
class B{
I impl;
}
我会用工厂模式,或者其他更灵活的方式得到A的实例(impl引用的)。
这样,我即使面临上述的变更,我的代码也不用改或者改动的地方非常少!
带橡皮的铅笔 tool();
tool.写();
tool.擦();诚心求教。
比如我要在一台机器上注册一些服务控件:OPC与Access组件,我是实现了一个RegistryServer服务基类,里面定义vector类型的变量用于给派生类使用,这样OPC与ACCESS类就可以各自绑定自己需要注册的文件名到vector,而注册方法大家都知道,相当简单,获取Dll中注册方法的入口点,然后去调用,这样,该方法明显的需要的需要被提升到基类,主程序也就相当简单了,谁知道过了几天,我们又需要一个PLC服务,结果可想而知,我不需要改动很多,只需要添加一个PLC对象进去就行了,// 可是我们在实际的编程中,很少用到继承!我写了这么多OO的代码,用了extends的代码比例很少。不过我常常用到继承,感觉相当优秀,因为有虚函数的存在。
class B extends A
一旦我这么写,那么就把B捆死在A上了。
现在假设A是针对Oracle的实现代码,现在我要做MYSQL的版本了(当然也要保持ORACLE的支持),你说我该怎么办???我在想你为什么不使用虚函数,你也学过C++吧,我想多态如何体现,在这里就不用说了吧。
用虚函数完全可以实现你的需求。#include <iostream.h>class A
{
public:
virtual void insert() { cout << "oracle insert version\n"; };
};class B : public A
{
public:
virtual void insert() { cout << "sql insert version\n"; }
};int main()
{
A *pA = new A();
A *pB = new B(); pA->insert();
pB->insert(); return 0;
}
========================
程序运行结果:
oracle insert version
sql insert version
========================
带橡皮的铅笔 tool();
tool.写();
tool.擦();诚心求教。
// 这个程序送给你,同时说明我所写程序均在VC6下调试通过。
// 此程序表明“带橡皮的铅笔”是由“铅笔”与“橡皮”组装而成的,不是派生。#include <iostream.h>class Pencil
{
public:
void Write() { cout << "Use Pencil Write\n"; };
};class Eraser
{
public:
void Clean() { cout << "Use Eraser Celan\n"; };
};class PencilPlugEraser
{
public:
void Write() { m_pencil.Write(); }
void Clean() { m_eraser.Clean(); }private:
Pencil m_pencil;
Eraser m_eraser;
};int main()
{
PencilPlugEraser pe;
pe.Write();
pe.Clean(); return 0;
}
=============================
程序运行结果:
Use Pencil Write
Use Eraser Celan
=============================好了,上班了,今天讨论到此。我给你回复了两次,半中腰IE都非法操作,看来机器不听话了。
作为对比,“眼”is a part of“头”是对的,但“头”is a“眼”是不对的,这一点跟“铅笔-带橡皮的铅笔”关系不同。
java的extends是扩展,并不能表达继承的全部概念,相当于C++ Public inhrit;而你说的带有橡皮的铅笔,可以在C++里用protected 继承的方式开实现.书中明确说了, 公有继承表示"Is A"的关系,是一个~!
私有继承表示"用实现" (implement with)
class PencilwithEraser : public Pencil, protected Eraser ;
在C++里这么表示的,Java里你可以用聚合表示.呵呵,这就是被质疑的多继承了.(据说C++的不好,但是Effeil很好)
作为对比,“眼”is a part of“头”是对的,但“头”is a“眼”是不对的,这一点跟“铅笔-带橡皮的铅笔”关系不同。
1:看来该我给你点分才对。
请问如何理解?2:你上面的 PencilPlugEraser 中,PencilPlugEraser::Write() 跟 Pencil::Write() 是没有任何必然联系的,是吧?
是,我说了我用组装来实现。3:那如果我想把 PencilPlugEraser 对象 cast 到一个 Pencil 就不行了吧?
如果是用继承实现的,将派生类对象cast到基类对象会产生对象的“切割”问题,
我想很多人都知道“切割”意味着什么。4:可实际上很有可能需要以“铅笔”的眼光去看待一个“带橡皮的铅笔”呀?
如果你需要铅笔,我想获取方法可以满足你:给类 PencilPlugEraser 中添加一个公有方法:
Pencil MyPencil() { return m_pencil; }
你现在已经有一支铅笔了,
顺便说一句,在你的问题被提出后,你自己思考过么?也就是说,你为什么不想想类可能很灵活的扩展。5:“铅笔” is a part of “带橡皮的铅笔”固然是没错的,但“带橡皮的铅笔” is a “铅笔”好像也没错啊?
实际当中的“带橡皮的铅笔”好像是组装而来的。
一个厂商或部门负责生产橡皮,另一个则负责生产铅笔(下面可能还能细分)
最后由一个厂商或部门组装。6:BTW
这是什么意思,我是一中专生,不理解。
Pencil MyPencil() { return m_pencil; }
Eraser MyEraser() { return m_eraser; }我左手一支铅笔,右手一块橡皮……如果用继承,单单的从“带橡皮的铅笔”中如何取出这两种对象?
请不要说cast……
你既然是你,既不是你爸,也不是你妈,不能用继承。
但是你总和你爸你妈有点关系的吧,怎么用java表达这种关系呢?
...
...
对啊,你是应该好好想想你到底是怎么来的?用has a 不对吗? 你难道 has not 你妈的基因 和你爸的基因吗?
> 请问如何理解? 由于你发的这个帖子,让我学到了不少东西,同时也见识了其他几位大家的手笔,在此一并表示感谢。如果你需要,我很愿意开一个送分的帖子,以示谢意。> 2:你上面的 PencilPlugEraser 中,PencilPlugEraser::Write() 跟 Pencil::Write() 是没有任何必然联系的,是吧?
> 是,我说了我用组装来实现。> 3:那如果我想把 PencilPlugEraser 对象 cast 到一个 Pencil 就不行了吧?
> 如果是用继承实现的,将派生类对象cast到基类对象会产生对象的“切割”问题,
> 我想很多人都知道“切割”意味着什么。 不好意思,我还真不知道“切割”是什么意思。如果你愿意,不妨给我扫扫盲。如果麻烦,一两句说不清楚就算了,我自己去网上搜。
本人不是科班出身,俗称的野路子,有些基本概念很不扎实,见笑了。> 4:可实际上很有可能需要以“铅笔”的眼光去看待一个“带橡皮的铅笔”呀?
> 如果你需要铅笔,我想获取方法可以满足你:给类 PencilPlugEraser 中添加一个公有方法:
> Pencil MyPencil() { return m_pencil; }
> 你现在已经有一支铅笔了,
> 顺便说一句,在你的问题被提出后,你自己思考过么?也就是说,你为什么不想想类可能很灵活的扩展。 我的问题在提给你之前,当然自己想过。我甚至想到了你可能会给出这样的解决方法。我只是觉得这种方法并不一定完全满足【以“铅笔”的眼光去看待一个“带橡皮的铅笔”】的需求。你这样虽然能看到一个“铅笔”,但它已经不是那个“带橡皮的铅笔”了,而只是个“不带橡皮的铅笔”,并不是以“铅笔”的*眼光*去看待一个“带橡皮的铅笔”。当然“铅笔-橡皮”这个例子也许不好,“橡皮”的存在并不能改变“铅笔”写出来的字的颜色。如果能的话,这种“获取方法”就力所不及了。> 5:“铅笔” is a part of “带橡皮的铅笔”固然是没错的,但“带橡皮的铅笔” is a “铅笔”好像也没错啊?
> 实际当中的“带橡皮的铅笔”好像是组装而来的。
> 一个厂商或部门负责生产橡皮,另一个则负责生产铅笔(下面可能还能细分)
> 最后由一个厂商或部门组装。 还是得说,这个“铅笔-橡皮”的例子不够准确,你可以更看重【“带橡皮的铅笔”是由“橡皮”和“铅笔”组装得来的】,而我更看重【“带橡皮的铅笔”既有“铅笔”的功能也有“橡皮”的功能】,所以,你看到的是“铅笔” is a part of “带橡皮的铅笔”,而我本来想的是“带橡皮的铅笔” is a “铅笔”。
还有你说的“把那个小橡皮从铅笔顶部的小圈中取出来”,显然也是因为你更看重它们的“组装关系”,那么在程序上“用组装来实现”也就顺理成章了。
误会。 既然这个例子如此不堪,还是忘了它吧。不过话说回来,你那个“公驴-母马-骡子”的例子也不好说明问题。虽然你说“用 C++ 的多重继承很容易实现”,但是:
class 骡子 : 公驴, 母马
是什么意思呢?继承了什么呢?能说清楚吗?你不妨把这个例子再细化一下,细到能说清楚的程度,再来考虑用 Java 怎么实现吧。
按照前面几位大侠的说法,如果我没理解错的话,这根本就不应该用“继承”来做的,何谈“很容易实现”?> 6:BTW
> 这是什么意思,我是一中专生,不理解。 By The Way.
to LifeAndC (蓝色忧郁)想想你是怎么来的?
你既然是你,既不是你爸,也不是你妈,不能用继承。
但是你总和你爸你妈有点关系的吧,怎么用java表达这种关系呢?
————————————————————————————————————————骡子、马和驴根本就是三类与父母和孩子的关系是不同的,最起码孩子还属于"人".而白娘子与许仙生的儿子就不能算作人。因为他是两个对象相互作用产生的对象。他父亲是class人的一个实例,他的母亲是 class 蛇 的一个实例。而这两个实例不发生作用的话,许仕林是根本不会产生的,更别提他所属的类别了。他们不可能是继承的关系。它是新的类型。
我只是觉得这种方法并不一定完全满足【以“铅笔”的眼光去看待一个“带橡皮的铅笔”】的需求。我觉得你还是没有理解。
PencilPlugEraser pe;
你需要铅笔:pe.MyPencil
你需要橡皮:pe.MyEraser
而你当前使用的是什么,想想看这里的this和pe,不就是带橡皮的铅笔么?关于对象的“切割”你可以参考《深入浅出MFC》第二章或《深度探索C++对象模型(应该是这本书)忘了。》
是什么意思呢?继承了什么呢?// 在语言上这里没有继承???
// 驴类
class CMule : public CMaleDonkey, CFemaleHorse
{
public:
CMule() { cout << "Mule Construction\n"; }
virtual void Born() { cout << "Mule Born\n"; }
};// 测试程序
int main()
{
// pMule的到来引发了基类构造的调用,这没有继承的缘故?
CMule *pMule = new CMule;
pMule->Born(); return 0;
}===========================
程序结果:
Male Donkey Construction
Female Horse Construction
Mule Construction
Mule Born
> // 驴类
> class CMule : public CMaleDonkey, CFemaleHorse我不是这个意思。你既然写成了这样,从语法上说,当然是继承,没有任何问题。问题在于,你这里的“多重继承”解决了现实世界中的什么问题呢?继承的是什么呢?是功能(functionality)?还是行为特点(behavior)?总要说清楚吧?你在开题的帖子里说的是,C++ 中的多重继承,在 Java 中怎么实现?那么,就应该举一个合适的例子,用 C++ 的“多重继承”可以很贴切地表达,然后让大家一起来看,用 Java 应该怎么写。程序语言是用来解决问题的,总要先把问题阐述清楚,然后才能对不同的解决方案进行比较。像你说的这个 class CMule 的例子,如果它本身都不是多“多重继承”的恰当应用,又怎么讨论“用 Java 怎么实现”呢?说实话,我本人一直也没能真正体会到“多重继承”的好处(或者说必要性),大概是因为“野路子出身”吧。所以很希望能看到一个恰当使用“多重继承”的例子。不过我倾向于认为,即使有这样的例子,用 Java 这种“单根继承”的语言,也会有合适的处理方法,即使不敢说比 C++ 的解决方案更好,总不至于差太远。毕竟 Java 比 C++ 晚出来这么长时间,发明 Java 的人绝对不笨,对于这种重大原则性的选择,应该是经过深思熟虑的。
}
abstract class 驴{
}
class 公驴 extends 驴{
}
class 母驴 extends 驴{
public 驴 交配(公驴 gl){}
public 骡子 交配(公驴 gm){}
}
abstract class 马{
}
class 公马 extends 马{
}
class 母马 extends 马{
public 马 交配(公马 gm){}
public 骡子 交配(公驴 gl){}
}
?从孔子到今天大概是80-90代吧,
那么继承的层次就有80-90层了哦~~
你这么想,你觉得是吗?————————————————————————————————凡事总是对比而言,不考虑环境因素的论点是没有存在的价值的如果不对,那么怎么理解“父” 类中的“父”字?英文对应的是parent吧?如果硬要细说当然不对,也不符合所谓的OOD准则大师讲过,要面向接口,尽量不要面向继承或抽象继承可我意识到哪个系统会死板到要求我们模拟孔子到现在的人的层次结构。不要咬字眼嘛,有什么意义,我不觉得这样理解会和闲来无事非要钻到donkey.fuck();里面去追究所谓的真理一样无聊