我决定开始自己做小编码项目,专注于代码质量而不是代码数量,并对抽象类的使用有疑问.
现在我知道抽象类和接口之间的区别与最大的接口(我认为)是接口允许您只定义需要使用接口和类的类实现的方法,允许您同时定义方法和成员如果您愿意,可以使用默认方法.我的问题是使用抽象类与普通类的主要好处是什么?我能想到的两者之间唯一真正的区别是你不能创建一个抽象类的实例.这两者之间还有其他差异吗?
我正在学习来自C++的C#并且遇到了问题.
我有一个抽象类AbstractWidget,一个接口IDoesCoolThings,以及一个派生自AbstractWidget的类,名为RealWidget:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget : IDoesCoolThings
{
void IDoesCoolThings.DoCool()
{
Console.Write("I did something cool.");
}
}
public class RealWidget : AbstractWidget
{
}
Run Code Online (Sandbox Code Playgroud)
当我实例化一个RealWidget对象并在其上调用DoCool()时,编译器给出了一个错误说法
'RealWidget'不包含'DoCool'的定义
我可以将RealWidget对象转换为IDoesCoolThings,然后调用就可以了,但这似乎是不必要的,我也失去了多态性(即使我定义了RealWidget.DoCool(),也总是会调用AbstractWidget.DoCool()).
我想解决方案很简单,但我尝试了各种各样的事情,因为我的生活无法想象这一点.
如果你有一个工厂类来创建某种新的对象,那个factroy类是一个单例,如下所示:
class Database_Factory extends Base_Factory {
private static $factory;
private $objects = array();
public function __get($profile) {
// check for object and return it if it's created before
}
public static function getInstance(){
if (!self::$factory)
self::$factory = new self();
return self::$factory;
}
}
Run Code Online (Sandbox Code Playgroud)
当某个对象需要它自己的工厂时,相同的代码会重复.所以我决定将这个工厂类抽象化,并且只为每个工厂实现特定的例程.但PHP不允许实例化抽象类.
abstract class Base_Factory {
public static function getInstance(){
if (!self::$factory)
self::$factory = new self();
return self::$factory;
}
}
Run Code Online (Sandbox Code Playgroud)
致命错误:无法实例化抽象类Base_Factory
你会怎么做?
可能重复:
何时使用接口而不是抽象类,反之亦然?
嗨,我正在向非程序员教授OOP概念.我想知道如何解释接口和抽象类之间的区别.
我实际上正在寻找的,是一个真实世界的例子,可以帮助突出两者之间的差异.
我需要定义一个接口,它必须强制执行某些运算符重载到实现它的类型.似乎没有一种明显的方法可以做到这一点,因为运算符重载必须在类中使用静态方法完成.有没有办法达到相同的效果(使用抽象类或其他任何东西)?
我在编译时遇到这个错误 - >不能将字段M1 :: sc声明为抽象类型I1,因为以下虚函数在I1中是纯的.请帮忙.
class I1
{
public:
virtual void a(int dir) = 0;
virtual void b() = 0;
virtual void c() = 0;
void a(int dir) {
....
}
void b() {
....
}
void c() {
....
}
};
class I2 : public I1
{
public:
void a(int dir) {
....
}
void b() {
....
}
void c() {
....
}
};
class M1 : public G1
{
protected:
I1 sc;
public:
int dir = 4; …Run Code Online (Sandbox Code Playgroud) 我已经对基本类和封装的想法感到满意,我已经开始着手理解多态,但我无法弄清楚如何使其工作.我搜索过的很多例子都是真的,非常强迫(类Foo和Bar对我来说太过抽象,看不到实用程序),但这就是我理解基本概念的方法:你编写一个基类,派生出一个从它改变基本方法所做的一切其他事情(但不是它们"是什么"),然后你可以编写通用函数来接受和处理任何派生类,因为你有点标准化它们的外观.在这个前提下,我试图实现基本的Animal-> cat/dog层次结构,如下所示:
class Animal {
public:
virtual void speak() = 0;
};
class Dog : public Animal {
public:
void speak() {cout << "Bark bark!" << endl;}
};
class Cat : public Animal {
public:
void speak() {cout << "Meow!" << endl;}
};
void speakTo(Animal animal) {
animal.speak();
}
Run Code Online (Sandbox Code Playgroud)
在哪里说话可以采取一般种类的动物,并使它,好吧,说话.但据我所知,这不起作用,因为我无法实例化Animal(特别是在函数参数中).我问,那么,我是否理解多态性的基本效用,我怎样才能真正做到我试图做的事情?
我有一个类是许多其他类的超类.我想知道(在我的超类的init()中,子类是否已覆盖特定方法.
我尝试使用类方法完成此操作,但结果是错误的:
class Super:
def __init__(self):
if self.method == Super.method:
print 'same'
else:
print 'different'
@classmethod
def method(cls):
pass
class Sub1(Super):
def method(self):
print 'hi'
class Sub2(Super):
pass
Super() # should be same
Sub1() # should be different
Sub2() # should be same
>>> same
>>> different
>>> different
Run Code Online (Sandbox Code Playgroud)
有没有办法让超类知道子类是否覆盖了一个方法?
正如您所知,您可以在Java 8中使用lambdas,例如替换匿名方法.
这里可以看到Java 7与Java 8的一个例子:
Runnable runnable = new Runnable() {
@Override
public void run() {
checkDirectory();
}
};
Run Code Online (Sandbox Code Playgroud)
在Java 8中可以表示为以下两种方式:
Runnable runnable = () -> checkDirectory();
Run Code Online (Sandbox Code Playgroud)
要么
Runnable runnable = this::checkDirectory;
Run Code Online (Sandbox Code Playgroud)
这是因为它Runnable是一个功能接口,只有一个(抽象)公共非默认方法.
但是......因为TimerTask我们有以下内容:
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
checkDirectory();
}
};
Run Code Online (Sandbox Code Playgroud)
看起来很熟悉吧?
使用lambda表达式不起作用,因为它TimerTask是一个抽象类,即使它只有一个抽象的公共非默认方法,它也不是一个接口,因此也没有功能接口.
它也没有重构为具有默认实现的接口,因为它带有状态,因此无法完成.
所以我的问题:构建时有没有办法使用lambdas TimerTask?
我想要的是以下内容:
Timer timer = new Timer();
timer.schedule(this::checkDirectory, 0, 1 * 1000);
Run Code Online (Sandbox Code Playgroud)
而不是一些丑陋的匿名内部类,有没有办法让它更好?
我知道在抽象类中,方法既可以是抽象的,也可以不是抽象的.但为什么我不能在"普通"非抽象类中创建抽象方法呢?
在此先感谢任何解释!
abstract-class ×10
interface ×3
abstract ×2
c# ×2
c++ ×2
class ×2
inheritance ×2
java ×2
oop ×2
java-8 ×1
lambda ×1
overriding ×1
php ×1
polymorphism ×1
python ×1
singleton ×1
timertask ×1