- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我听说 VBA 缺乏继承。我做了一些解决方法,现在在我看来,这正是继承所做的。我离 pro =) 很远,可能遗漏了一些东西。因此,我非常感谢您对可能存在的缺点的想法。
当我发现你仍然可以在一个接口(interface)类中实现一个功能的完整实现时,我感到非常惊讶(不仅仅是一个签名),这让我想到了下面的内容。我看到有些人在组合的帮助下做了类似的事情,但他们只在界面中使用了一个签名。
IBird - 类
Public Sub SayFromInterface()
Debug.Print "Tweet from IBird"
End Sub
Public Sub SayFromInstance()
End Sub
乌鸦级
Implements IBird
Private pBird As IBird
Private Sub Class_Initialize()
Set pBird = New IBird
End Sub
'let you use already implemented code from "abstract class", to avoid
'duplicating your code, which is the main point of inheritance
'in my opinion
Public Sub IBird_SayFromInterface()
pBird.SayFromInterface
End Sub
'you can override the IBird function (common use)
Public Sub IBird_SayFromInstance()
Debug.Print "Tweet from Crow"
End Sub
测试 - 模块
Sub testIBird()
Dim Bird As IBird
Set Bird = New Crow
Bird.SayFromInterface
Bird.SayFromInstance
Debug.Print TypeName(Bird)
Debug.Print TypeOf Bird Is IBird
End Sub
输出:
Tweet from IBird
Tweet from Crow
Crow
True
最佳答案
那是组合,而不是继承 - 是的,通过组合,您基本上可以模拟继承。如果该类实现封装对象的接口(interface),那么事情开始看起来像某种装饰器模式。
除非您在IBird
中没有任何实现代码。接口(interface)应该是纯抽象的。制作一个应该是接口(interface)的 New
实例,使该类不再是接口(interface):现在它只是另一个类,暴露了任何其他类都可以实现的默认接口(interface),而 I
前缀变得相当困惑:
Set pBird = New IBird
很奇怪,客户端代码现在需要想知道他们是想让那只鸟鸣叫 FromInstance
还是 FromInterface
- 这些是非常“元”的标识符,可以使事情 < em>不像继承一样工作。
如果我们有一个 Crow : Bird
,其中 Bird
有 IBird.Chirp
的实现:
public virtual string Chirp() => "Chirp!";
...然后 Crow
有这个:
public override string Chirp() => "Craaaw!";
然后调用哪个方法取决于运行时类型 - 这应该很明显:
IBird bird1 = new Bird();
bird1.Chirp(); // "Chirp!"
IBird bird2 = new Crow();
bird2.Chirp(); // "Craaaw!"
然而想象一个接收IBird
参数的方法:
public void DoSomething(IBird bird)
{
Debug.Print(bird.Chirp());
}
如果 bird
是 Bird
,它会打印“Chirp!”;如果 bird
是 Crow
,它会打印“Craaaw!”:要运行的方法是最派生的覆盖,不一定定义在最派生的类型。
继承将允许 GiantCrow : Crow
从 Crow
继承 Chirp
方法并且不一定覆盖它. 那是您无法用 VBA 类模拟的:您被迫编写等同于...
public override string Chirp() => base.Chirp();
...这在技术上是多余的,如果您每次都必须这样做只是为了让“基本”成员在您的默认界面上可见,那么会变得非常重复。
我们实际上包装调用封装对象,而不是继承基成员。 装饰器 模式正是这样做的,它为您提供了一种扩展 VBA 类或接口(interface)的非侵入式方法。
装饰器实现它扩展的接口(interface),并封装该类型的私有(private)实例。所以基本上使用装饰器的“乌鸦继承层次结构”设置看起来像这样:
Dim bird As IBird
Set bird = Crow.Create(New BaseBird)
也许更合适的装饰器模式示例可能是:
Dim repository As IRepository
Set repository = LoggingRepository.Create(BirdRepository.Create(connectionString), New DebugLogger)
其中 BirdRepository
负责抽象与某些 Birds
表相关的数据库操作(BirdRepository
实现 IRepository
),其中 LoggingRepository
是一个装饰器,它也实现了 IRepository
,但也包装了一个 IRepository
实例(在本例中为 BirdRepository
)添加自己的功能 - 可能如下所示:
'@PredeclaredId
Implements IRepository
Private loggerInternal As ILogger
Private wrappedInternal As IRepository
Public Function Create(ByVal internal As IRepository, ByVal logger As ILogger) As IRepository
Dim result As LoggingRepository
Set result.Wrapped = internal
Set result.Log = logger
Set Create = result
End Function
Public Property Get Wrapped() As IRepository
Set Wrapped = wrappedInternal
End Property
Public Property Set Wrapped(ByVal value As IRepository)
If Not wrappedInternal Is Nothing Then Err.Raise 5, TypeName(Me), "Instance is already initialized."
Set wrappedInternal = value
End Property
Public Property Get Log() As ILogger
Set Log = loggerInternal
End Property
Public Property Set Log(ByVal value As ILogger)
If Not loggerInternal Is Nothing Then Err.Raise 5, TypeName(Me), "Instance is already initialized."
Set loggerInternal = value
End Property
Private Function IRepository_SelectAll() As Object
Log.Info "Starting IRepository.SelectAll"
Dim t As Double
t = Timer
Set IRepository_SelectAll = wrappedInternal.SelectAll
Log.Info "IRepository.SelectAll completed in " & Timer - t & " seconds."
End Function
Private Sub IRepository_Delete(ByVal id As Long)
Log.Info "Starting IRepository.Delete(" & id & ")"
Dim t As Double
t = Timer
wrappedInternal.Delete id
Log.Info "IRepository.Delete completed in " & Timer - t & " seconds."
End Sub
Private Sub IRepository_Save(ByVal entity As Object)
'...
wrappedInternal.Save entity
'...
End Sub
'...
被赋予 IRepository
对象的方法不能(而且绝对不应该)知道它是否被赋予了一个普通的 BirdRepository
,一个 LoggingRepository
包装一个 BirdRepository
,或者一个 FakeRepository
封装一个 Collection
而不是访问数据库表 - 这种多态性是整点。
这是一种不使用继承来扩展类型的方法,VBA 绝对可以利用它而不会过多地破坏模式。但这不是继承。
关于VBA继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57641543/
我使用的是 PHP 5.3 稳定版,有时会遇到非常不一致的行为。据我所知,在继承中,父类(super class)中的所有属性和方法(私有(private)、公共(public)和 protected
所以我一直在努力寻找正确的方法来让应该非常简单的继承发挥作用(以我想要的方式 ;)),但我失败得很惨。考虑一下: class Parent { public String name = "Pare
给定这些类: class Father { public Father getMe() { return this; } } class Child extends Father {
为什么最后打印“I'm a Child Class”。 ? public class Parent { String parentString; public Parent()
我知道有很多类似的问题对此有很多很好的答案。我试着看看经典的继承方法,或者那些闭包方法等。不知何故,我认为它们对我来说或多或少是“hack”方法,因为它并不是 javascript 设计的真正目的。
我已经使用表单继承有一段时间了,但没有对以下方法进行太多研究。只需创建一个新类而不是表单并从现有表单继承并根据需要将所需控件转换为 protected 。 Visual Studio 2010 设计器
我原以为下面的代码片段会产生编译错误,因为派生类不会有我试图在 pub_fun() 中访问的 priv_var。但是它编译了,我得到了下面提到的输出。有人可以解释这背后的理论吗? class base
继承的替代方案有哪些? 最佳答案 Effective Java:优先考虑组合而不是继承。 (这实际上也来自《四人帮》)。 他提出的情况是,如果扩展类没有明确设计为继承,继承可能会导致许多不恰当的副作用
我有2个类别:动物( parent )和狗(动物的“ child ”),当我创建一个 Animal 对象并尝试提醒该动物的名称时,我得到了 undefined ,而不是她的真名。为什么?(抱歉重复发帖
我试图做继承,但没想到this.array会像静态成员一样。我怎样才能让它成为“ protected /公开的”: function A() { this.array = []; } func
在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。代码更容易解释: class Parent { List> processors; private void do
如果我有一个对象,我想从“ super 对象”“继承”方法以确保一致性。它们将是混合变量。 修订 ParentObj = function() { var self = this; t
class Base { int x=1; void show() { System.out.println(x); } } class Chi
目前我正在尝试几种不同的 Javascript 继承方法。我有以下代码: (“借用”自 http://www.kevlindev.com/tutorials/javascript/inheritanc
我在 .popin-foto 元素中打开一个 popin。当我尝试在同一元素中打开子类 popin 时,它不起作用。 代码 这是 parent function Popin(container, ti
我有以下两个类: class MyClass { friend ostream& operatorvalue +=1; return *this; } 现在
有没有办法完全忽略导入到 html 文件中的 header 中的 CSS 文件? 我希望一个页面拥有自己独立的 CSS,而不是从任何其他 CSS 源继承。 最佳答案 您可以在本地样式表中使用 !imp
Douglas Crockford似乎喜欢下面的继承方式: if (typeof Object.create !== 'function') { Object.create = functio
假设我有以下代码: interface ISomeInterface { void DoSomething(); void A(); void B(); } public
class LinkedList{ public: int data; LinkedList *next; }; class NewLinkedList: public Lin
我是一名优秀的程序员,十分优秀!