假设我有一个叫做矩形的超类:
classdef Rectangle
properties
width
height
x0 = 0
y0 = 0
angle = 0
end
methods
function obj = Rectangle(x0, y0, width, height, angle)
obj.x0 = x0;
obj.y0 = y0;
obj.width = width;
obj.height = height;
obj.angle = angle;
end
end
end
我有一个名为Map的子类,我希望所有属性在设置后都是只读的:
classdef Map < Rectangle
properties (SetAccess=private)
filename
end
methods
function obj = Map(filename)
% Get info from map using a function that uses geotiffread
[x0, y0, width, height] = GetInfoFromMap(filename);
obj = obj@Rectangle(x0, y0, width, height, 0);
obj.filename = filename;
end
end
end
如何在Map中将Rectangle的继承属性设为只读?我希望任何独立(非Map)Rectangle对象的属性保持可变。
而且,我如何确保其中一些属性只能采用某些值?即为了我的目的,一个矩形可以有任何角度,但我希望一个地图总是有一个0的角度。但如果我尝试为Map创建一个set.angle方法,以确保角度只能是0,我得到一个错误告诉我“无法在类'BackgroundMap'中为属性'angle'指定一个set函数,因为该属性不是由该类定义的。”
答案 0 :(得分:2)
这似乎是一种情况,你应该更喜欢组合而不是继承。
在其中一条评论(@ Dev-iL)中提到了这个想法,其中它被描述为“不是非常OOP”。我不同意 - 虽然在许多情况下继承是正确的设计,但组合通常更可取。 (有关此问题的一些讨论,请参阅here和here)。人们可能更喜欢组合的一个典型原因是继承将子类暴露给超类的细节,换句话说它破坏了封装 - 这就是Rectangle
和Map
的实现中发生的事情。
我建议代替Map
从Rectangle
继承,它应该有Rectangle
作为私有(可能是隐藏的)属性。所以你应该把地图看成不是一种矩形,而是要有一个相关的矩形,它委托它的一些功能。
完成后,您可以为Map
提供一些属性width
,height
等,并将其设为GetAccess=public, SetAccess=private, Dependent
。然后在Map
中,为每个方法添加get
方法,只获取基础Rectangle
的属性并将其传递通过。请注意,Map
不需要角度属性,因为它始终为零。
classdef Map < handle
properties (SetAccess=private)
filename
end
properties (Hidden, GetAccess = private, SetAccess-private)
rectangleDelegate
end
properties (Dependent, GetAccess = public, SetAccess = private)
width
height
x0
y0
end
methods
function obj = Map(filename)
% Get info from map using a function that uses geotiffread
[x0, y0, width, height] = GetInfoFromMap(filename);
obj.rectangleDelegate = Rectangle(x0, y0, width, height, 0);
obj.filename = filename;
end
end
methods
function val = get.width(obj)
val = obj.rectangleDelegate.width;
end
% other gets
end
end