MATLAB:将继承的属性设置为只读
MATLAB: Set inherited properties to read-only
假设我有一个名为 rectangle 的超类:
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 的继承属性设置为只读?我希望任何独立(非地图)矩形对象的属性保持可变。
另外,我如何确保其中一些属性只能采用特定值?即出于我的目的,矩形可以有任何角度,但我希望地图的角度始终为 0。但是如果我尝试为地图创建 set.angle 方法以确保角度只能为 0,我收到一条错误消息,告诉我 "Cannot specify a set function for property 'angle' in class 'BackgroundMap', because that property is not defined by that class."
这似乎是您应该更喜欢组合而不是继承的情况。
这个想法在评论之一 (@Dev-iL) 中被提及,它被描述为 "not very OOP"。我不同意——尽管在许多情况下继承是正确的设计,但组合通常更可取。 (有关相关讨论,请参阅 here and 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
假设我有一个名为 rectangle 的超类:
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 的继承属性设置为只读?我希望任何独立(非地图)矩形对象的属性保持可变。
另外,我如何确保其中一些属性只能采用特定值?即出于我的目的,矩形可以有任何角度,但我希望地图的角度始终为 0。但是如果我尝试为地图创建 set.angle 方法以确保角度只能为 0,我收到一条错误消息,告诉我 "Cannot specify a set function for property 'angle' in class 'BackgroundMap', because that property is not defined by that class."
这似乎是您应该更喜欢组合而不是继承的情况。
这个想法在评论之一 (@Dev-iL) 中被提及,它被描述为 "not very OOP"。我不同意——尽管在许多情况下继承是正确的设计,但组合通常更可取。 (有关相关讨论,请参阅 here and 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