我的班级应该同时扩展两个班级:
public class Preferences extends AbstractBillingActivity {
public class Preferences extends PreferenceActivity {
Run Code Online (Sandbox Code Playgroud)
怎么办?
更新.由于这是不可能的,那么我应该如何将这个AbstractBillingActivity与Preferences一起使用呢?
Upd2.如果我使用接口,我应该创建:
BillingInterface
public interface BillingInterface extends PreferenceActivity, AbstractBillingActivity {
}
Run Code Online (Sandbox Code Playgroud)PreferenceActivity
public interface PreferenceActivity {
}
Run Code Online (Sandbox Code Playgroud)AbstractBillingActivity
public interface AbstractBillingActivity {
void onCreate(Bundle savedInstanceState);
}
Run Code Online (Sandbox Code Playgroud)然后
public class Preferences implements BillingInterface {
Run Code Online (Sandbox Code Playgroud) template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
Run Code Online (Sandbox Code Playgroud)
我从GCC得到这些错误:
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member …Run Code Online (Sandbox Code Playgroud) 有两个基类具有相同的函数名.我想继承它们,并以不同的方式搭乘每种方法.如何使用单独的声明和定义(而不是在类定义中定义)?
#include <cstdio>
class Interface1{
public:
virtual void Name() = 0;
};
class Interface2
{
public:
virtual void Name() = 0;
};
class RealClass: public Interface1, public Interface2
{
public:
virtual void Interface1::Name()
{
printf("Interface1 OK?\n");
}
virtual void Interface2::Name()
{
printf("Interface2 OK?\n");
}
};
int main()
{
Interface1 *p = new RealClass();
p->Name();
Interface2 *q = reinterpret_cast<RealClass*>(p);
q->Name();
}
Run Code Online (Sandbox Code Playgroud)
我没能在VC8中移出定义.我发现Microsoft特定关键字__interface可以成功完成这项工作,代码如下:
#include <cstdio>
__interface Interface1{
virtual void Name() = 0;
};
__interface Interface2
{
virtual void Name() = 0;
}; …Run Code Online (Sandbox Code Playgroud) http://en.wikipedia.org/wiki/Diamond_problem
我知道这意味着什么,但我可以采取哪些措施来避免它?
我和一位同事对多重继承有一点争论.我说它不受支持,而且他说的是.所以,我以为我会问网上那些聪明的人.
我遇到过许多反对在C#中包含多重继承的论据,其中一些包括(除了哲学论证):
我来自C++背景,错过了多重继承的力量和优雅.虽然它不适合所有软件设计,但在某些情况下很难否认它在接口,组合和类似的OO技术上的实用性.
是否排除了多重继承,说开发人员不够聪明,不能明智地使用它们,并且在它们出现时无法解决这些复杂问题?
我个人欢迎将多重继承引入C#(也许是C##).
附录:我很想知道来自单一(或程序背景)与多重继承背景的回复.我经常发现,没有多重继承经验的开发人员通常会默认使用多继承是不必要的参数,因为他们没有任何关于范例的经验.
首先......对不起这篇文章.我知道stackoverflow上有很多帖子正在讨论多重继承.但我已经知道Java不支持多重继承,我知道使用接口应该是另一种选择.但我不明白并看到我的困境:
我必须对用Java编写的非常大且复杂的工具进行更改.在此工具中,有一个数据结构,它由许多不同的类对象构建,并具有链接的成员层次结构.无论如何...
Tagged具有多个方法的类,并根据对象的类返回一个对象标记.它需要成员和静态变量.XMLElement允许链接对象,最后生成一个XML文件.我还需要成员和静态变量.XMLElement,其中一些Tagged.好的,这不会起作用,因为它只能扩展一个类.我经常读到Java的所有内容都没问题,也没有必要进行多重继承.我相信,但我不知道接口应如何取代继承.
我真的不明白所以请有人解释我如何处理这个问题?
最近我遇到了一个use在类定义中使用语句的类.
有人可以解释它到底做了什么 - 因为我找不到任何有关它的信息.
我理解它可能是一种将它从给定文件的全局范围移开的方式,但它是否也允许给定的类继承多个父类 - 因为extends只允许一个父类引用?
我看到的例子是Laravel原始安装的User模型:
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array('password', 'remember_token');
}
Run Code Online (Sandbox Code Playgroud)
我已经看到这个模型的一些例子实际上使用了UserTrait类中包含的方法- 因此我怀疑,但我真的想了解更多关于所附use语句的含义.
PHP文档说:
use关键字必须在文件的最外层范围(全局范围)或命名空间内声明中声明.这是因为导入是在编译时完成的,而不是运行时,所以它不能是块作用域.以下示例将显示use关键字的非法使用: …
在Java中执行此操作是合法的:
void spew(Appendable x)
{
x.append("Bleah!\n");
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做(语法不合法):
void spew(Appendable & Closeable x)
{
x.append("Bleah!\n");
if (timeToClose())
x.close();
}
Run Code Online (Sandbox Code Playgroud)
我希望尽可能强制调用者使用Appendable和Closeable的对象,而不需要特定的类型.有多个标准类可以执行此操作,例如BufferedWriter,PrintStream等.
如果我定义自己的界面
interface AppendableAndCloseable extends Appendable, Closeable {}
Run Code Online (Sandbox Code Playgroud)
因为实现Appendable和Closeable的标准类没有实现我的接口AppendableAndCloseable(除非我不理解Java以及我认为我做的...空接口仍然在其超级接口之上和之外添加唯一性),这将无法工作.
我能想到的最接近的是做以下其中一项:
选择一个接口(例如Appendable),并使用运行时测试来确保参数是instanceof其他参数.缺点:编译时没有遇到问题.
需要多个参数(捕获编译时正确但看起来很笨):
void spew(Appendable xAppend, Closeable xClose)
{
xAppend.append("Bleah!\n");
if (timeToClose())
xClose.close();
}
Run Code Online (Sandbox Code Playgroud)我想使用Mixin总是为我的子类添加一些init功能,每个类继承自不同的API基类.具体来说,我想创建多个不同的子类,这些子类继承自这些不同的API提供的基类之一和一个Mixin,它将始终以相同的方式执行Mixin初始化代码,而无需代码复制.但是,似乎不会调用Mixin类的__init__函数,除非我在Child类的__init__函数中显式调用它,这不是理想的.我建立了一个简单的测试用例:
class APIBaseClassOne(object):
def __init__(self, *args, **kwargs):
print (" base ")
class SomeMixin(object):
def __init__(self, *args, **kwargs):
print (" mixin before ")
super(SomeMixin, self).__init__(*args, **kwargs)
print (" mixin after ")
class MyClass(APIBaseClassOne):
pass
class MixedClass(MyClass, SomeMixin):
pass
Run Code Online (Sandbox Code Playgroud)
正如您在以下输出中所看到的,Mixin函数的init永远不会被调用:
>>> import test
>>> test.MixedClass()
base
<test.MixedClass object at 0x1004cc850>
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点(在调用Mixin时有一个init函数)而不编写每个子类来显式调用Mixin的init函数?(即,不必在每个班级做这样的事:)
class MixedClass(MyClass, SomeMixin):
def __init__(*args, **kwargs):
SomeMixin.__init__(self, *args, **kwargs)
MyClass.__init__(self, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果我所有的子类都继承自相同的基类,我意识到我可以创建一个继承自基类和mixin的新中间类,并保持干燥.但是,它们从具有共同功能的不同基类继承.(准确地说是Django Field类).
c++ ×3
inheritance ×3
java ×3
c# ×2
oop ×2
ambiguous ×1
android ×1
gcc ×1
interface ×1
mixins ×1
namespaces ×1
php ×1
python ×1
visual-c++ ×1