As an example, suppose I have created an abstract class called Shape and two subclasses called Circle and Rectangle that both implement an (abstract) method called Draw. I would like to be able to create a number of Circle and Rectangle objects, store them in an array and call Draw on each array object by iterating through the array.
I have tried something like the following:
Shape.m:
classdef (Abstract) Shape < handle
methods (Abstract)
Draw(obj);
end
end
Circle.m:
classdef Circle < Shape
methods
function obj = Draw(obj)
disp('This is a circle');
end
end
end
Rectangle.m:
classdef Rectangle < Shape
methods
function obj = Draw(obj)
disp('This is a rectangle');
end
end
end
test.m:
shapes = Shape.empty();
myrect = Rectangle();
mycirc = Circle();
shapes(end + 1) = myrect;
shapes(end + 1) = mycirc;
for i = 1:size(shapes,1)
shapes(i).Draw();
end
When I try to run test.m, I get the following error message:
Error using Shape.empty
Abstract classes cannot be instantiated.
Class 'Shape' defines abstract methods
and/or properties.
Error in test (line 1)
shapes = Shape.empty();
As is clear from the error, you cannot instantiate an abstract class (see sebastian's answer for details). However, there is a special superclass called matlab.mixin.Heterogeneous from which you can derive to allow creation of an array of different classes.
First, derive from matlab.mixin.Heterogeneous in Shape.m:
classdef (Abstract) Shape < handle & matlab.mixin.Heterogeneous
Then in your test script, initialize shapes from either Circle or Rectangle:
shapes = Circle.empty();
When you run the loop, the array will change class:
>> shapes
shapes =
1x2 heterogeneous Shape (Rectangle, Circle) array with no properties.
>> shapes(1)
ans =
Rectangle with no properties.
>> shapes(2)
ans =
Circle with no properties.
That should be all you need, but for additional control over a heterogeneous array, you can override the getDefaultScalarElement method of matlab.mixin.Heterogeneous to specify the default object. This should be overridden for abstract base classes:
Override this method if the Root Class is abstract or is not an appropriate default object for the classes in the heterogeneous hierarchy. getDefaultScalarElement must return an instance of another member of the heterogeneous hierarchy.
Say you want the default object to be Circle for an array of objects deriving from Shape:
methods (Static, Sealed, Access = protected)
function default_object = getDefaultScalarElement
default_object = Circle;
end
end
Now missing elements in an array of objects derived from Shape will be filled with Circle objects:
>> clear r
>> r(2) = Rectangle
r =
1x2 heterogeneous Shape (Circle, Rectangle) array with no properties.
>> r(1)
ans =
Circle with no properties.
>> r(2)
ans =
Rectangle with no properties.
From the docs:
abstract class — A class that cannot be instantiated, but that defines class components used by subclasses.
See: Mathworks-Docs
Which is, afaik, the definition of abstract classes in other programming languages as well (someone correct me if I'm wrong).
So to construct an array that holds various kinds of Shape elements, I'd guess you'll either have to make Shape non-abstract or implement another non-abstract class, that all your real implementations inherit from.
EDIT: For completeness:
I tried what you're trying achieve and at first sight, object-arrays with mixed elements that have a common superclass don't exist:
>> objects(1) = Foo();
>> objects(2) = FooBar();
The following error occurred converting from FooBar to Foo:
Error using Foo
Too many input arguments.
>> FooBar
ans =
FooBar handle with no properties.
Methods, Events, Superclasses
Superclasses for class FooBar:
Foo
handle
EDIT 2:
See chappjc's solution for this issue ;)
Related
I would like some help understanding what does self refers to in this case. I understand that self refers to the class, module, etc that "owns" the code currently executing. In my example, my_each is an instance method for the Enumerable module. I'd like to know how does the self keyword works so that when I pass it to my example array it references it.
module Enumerable
def my_each
i = 0
while i < self.size
yield(self[i])
i += 1
end
self
end
end
[2,4,5].my_each { |i|
puts i
}
=> 2
=> 4
=> 5
What self refers to depends on the context. In your case, in an instance method, self refers to the object receiver of your instance method, so in your case the array [2, 4, 5].
But self can refer to other objects too. For example,
class Foo
puts self
end
prints Foo because in that context self refers to the class object. And that's why the two following definitions are the same thing
class Foo
def Foo.m
end
end
class Foo
def self.m
end
end
In Ruby it's all about self and every method is always executed against a particular self.
In your example instance method my_each self will refer to an instance which is using the method.
As you said self can also refer to a class, module..
It is a very powerfull ruby keyword since it can be used to create metaclasses.
If you are interested in understanding more I suggest you read chapter 5 in The Well Grounded Rubyist
self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everywhere:
For instance variables: #myvar
For method and constant lookup
When defining methods, classes and modules.
Inside of an instance method
In the code below, reflect is an instance method. It belongs to the object we created via Event.new. So self points to that object.
class Event
def reflect
self
end
end
g = Event.new
g.reflect == g # => true
Inside of a class method
For this example, reflect is a class method of Ghost. With class methods, the class itself "owns" the method. self points to the class.
class Event
def self.reflect
self
end
end
Event.reflect == Event # => true
It works the same with "class" methods inside of modules. For example:
module Event
def self.reflect
self
end
end
Event.reflect == Event # => true
Remember, classes and modules are treated as objects in Ruby. So this behavior isn't that different from the instance method behavior we saw in the first example.
Inside of a class or module definition
One feature of Ruby that makes it such a good fit for frameworks like Rails is that you can execute arbitrary code inside class and module definitions. When you put code inside of a class/module definition, it runs just like any other Ruby code. The only real difference is the value of self.
As you can see below, self points to the class or module that's in the process of being defined.
class Event
self == Event # => true
end
module Join
self == Join # => true
end
Inside mixin methods
Mixed-in methods behave just like "normal" instance or class methods when it comes to self. This makes sense. Otherwise the mixin wouldn't be able to interact with the class you mixed it into.
Instance methods
Even though the reflect method as defined in the module, its self is the instance of the class it was mixed into.
module Reflection
def reflect
self
end
end
class Event
include Reflection
end
g = Event.new
g.reflect == g # => true
Class methods
When we extend a class to mix in class methods, self behaves exactly like it does in normal class methods.
module Reflection
def reflect
self
end
end
class Event
extend Reflection
end
Event.reflect == Event # => true
Inside the metaclass
Chances are you've seen this popular shortcut for defining lots of class methods at once.
class Event
class << self
def method1
end
def method2
end
end
end
The class << foo syntax is actually pretty interesting. It lets you access an object's metaclass - which is also called the "singleton class" or "eigenclass." I plan on covering metaclasses more deeply in a future post. But for now, you just need to know that the metaclass is where Ruby stores methods that are unique to a specific object.
If you access self from inside the class << foo block, you get the metaclass.
class << "test"
puts self.inspect
end
# => #<Class:#<String:0x007f8de283bd88>
Outside of any class
If you're running code outside of any class, Ruby still provides self. It points to "main", which is an instance of Object:
puts self.inspect # => main
I'd like to understand how Matlab works with array objecs. I've read several posts and the Matlab help for this topic, but I still don't understand it completely.
Let's take a use case: I'd like to manage several measurement channels (the amount of channels can vary). Each measurement channel is an object with several properties. Now I'd like to have a class handling the channels (channelHandler.m). In this class I can simply add a new channel to the array (later on there might be bore functionality).
So what I've tried so far:
1) create the measurementChannel.m class
In the constructor I've only set the channel name so far without data.
classdef measurementChannel
%CHANNEL holds an instance of a single channel
properties
channelData
channelName = strings
channelUnit = strings
channelDataLength
channelOriginMeasurementFile
end
methods
function obj = channelTest(channelName)
if nargin > 0
obj.channelName = channelName;
end
end
end
end
To test this class I tried this:
channel(1) = measurementChannel('channelA');
channel(2) = measurementChannel('channelB');
channel(1).channelName
channel(2).channelName
which was working well.
2) Now I've created the channelHandler class:
classdef channelHandler
properties (Access = public)
channelArray
end
methods (Access = public)
function addChannel(obj, Name)
testobj = measurementChannel();
testobj.channelName = Name;
obj.channelArray = [obj.channelArray testobj];
end
end
and access this by using the following commands:
createChannels = channelHandler();
createChannels.addChannel('channel1');
createChannels.addChannel('channel2');
createChannels.channelArray(1).channelName
createChannels.channelArray(2).channelName
this fails because channelArray is not defined as an array and will give an error accessing channelArray(2).
So I also tried to initialize the array (but then I need to know the amount of channels).
so my questions are:
a) do I really need to initialize an array of objects?
b) how can I fix the channelHandler class to add objects to the array?
The issue is that you are not inheriting from the handle class and therefore the modifications made within addChannel alter a copy of your object rather than the object itself. If you inherit from handle, the code that you have pasted will work just fine.
classdef channelHandler < handle
This is a question about OWL (Web Ontology Language). There might be some mistakes of terms as I am a very beginner.
I want to represent a painting activity as a Painting class.
Painting has a property TargetSurface whose range is a Surface class:
Surface has properties SurfaceColor (range: Color), etc.
Painting has a property TargetColor whose range is a Color class.
Now I want to represent the objective of painting as a property of Painting. It would be something like: a property Painting.Objective has a range that is an instance of Change class (let's say, Change1), which involves properties Change1.What = TargetSurface.SurfaceColor and Change1.ToWhat = TargetColor.
My question is that Objective is referring to properties of Painting (Painting is a holder of Objective; referred properties are Painting.TargetSurface.SurfaceColor and Painting.TargetColor). How can we represent this in OWL? An ugly solution would be representing the properties of Change1 as xsd:string; Change1.What = "parent.TargetSurface.SurfaceColor" and Change1.ToWhat = "parent.TargetColor". Are there better solutions?
Note that Painting.TargetSurface and Painting.TargetColor will be referred to in other properties of Painting. So making an instance Change2 which directly refers to Painting.TargetSurface.SurfaceColor and Painting.TargetColor would not be a good idea.
Many thanks!
You can do this with "punning" in OWL2. Punning takes advantage of the fact that properties are objects too. We do something similar when modeling property attributes. We can use the property in the subject position of a triple when specifying the domain attribute, e.g. TargetSurface rdfs:range Surface. You can similarly specify rdf:Property in the object position of the rdfs:range assertion for your What property. An example assertion could be Change1 What TargetColor where Change1 is your individual change of the painting, What is the property and TargetColor is the property that is changed (which is used here as the object of the triple).
From the answer of #Jess, a solution came up to my mind.
We prepare two general classes. Holder class (properties Context, HeldVia) refers to a class that holds a class Context as a property HeldVia. Ref class (properties A, B) refers to a class that is held by A as a property B (i.e. like an A.B operator).
Then we can represent Painting.Objective as follows. An informative representation would be:
Painting.Objective = Change1
Change1.What = Ref(Ref(Holder(Change1,Objective),TargetSurface),SurfaceColor)
Change1.ToWhat = Ref(Holder(Change1,Objective),TargetColor)
Note that Holder(Change1,Objective) refers to Painting since Painting is holding Change1 as an Objective property.
More formally, the above would be represented as:
Painting.Objective = Change1
Holder1.Context = Change1
Holder1.HeldVia = Objective
Ref1.A = Holder1
Ref1.B = TargetSurface
Ref2.A = Ref1
Ref2.B = SurfaceColor
Ref3.A = Holder1
Ref3.B = TargetColor
Change1.What = Ref2
Change1.ToWhat = Ref3
When a WPF item is frozen, the docs says it cannot be changed. I'm just not very sure what "change" mean by in this context.
For example, if I create an instance of a shape and then freeze it, is it possible to do things like rotate or translate it even though it is frozen?
Short answer:
Once an object is frozen, you cannot modify any properties on it. This applies recursively.
Longer answer:
First of all, the Shape class (and thus Path, Ellipse, Rectangle etc.) are not freezable.
But assuming you are talking about Geometry, which is freezable, then the general answer is no, because attempting to modify properties of a frozen object is not possible. For example, the following code will throw an exception
var geo = new LineGeometry();
geo.Freeze();
// InvalidOperationException:
geo.Transform = new TranslateTransform(10, 10);
And freezing is recursive, so its not possible to cheat the system like this:
var tx = new TranslateTransform(10, 10);
var geo = new LineGeometry();
geo.Transform = tx;
geo.Freeze();
// InvalidOperationException:
tx.X = 20;
But, back to your original question about shapes, which are constructed out of geometries (but doesn't derive from them).
You can freeze the geometry of your shape, and still apply transformations to that shape. This works because the transform is on the shape object, and not on the freezable:
var geo = new LineGeometry(new Point(0,0), new Point(10,10));
geo.Freeze();
var myShape = new Path { Data = geo };
// This is fine, even though the geometry is frozen
myShape.RenderTransform = new TranslateTransform(10, 10);
This is just basic example:
if (a == b)
{
textBox1.Text = "a == b";
textBox1.IsEnabled = true;
textBox2.Text = "EXAMPLE2";
textBox2.IsEnabled = false;
textBox3.Text = "EXAMPLE3";
textBox3.IsEnabled = false;
textBox4.Text = "EXAMPLE4";
textBox4.IsEnabled = false;
textBox5.Text = "EXAMPLE5";
textBox5.IsEnabled = false;
}
else
{
textBox1.Text = "a != b";
textBox1.IsEnabled = false;
textBox2.Text = "EXAMPLE2";
textBox2.IsEnabled = true;
textBox3.Text = "EXAMPLE3";
textBox3.IsEnabled = true;
textBox4.Text = "EXAMPLE4";
textBox4.IsEnabled = true;
textBox5.Text = "EXAMPLE5";
textBox5.IsEnabled = true;
}
This seems pretty tedious. I was wondering if there's a better way to handle situations like that? I just have this feeling that all the Pros out there don't do things using this 1x1x1x.... method.
There are lots of ways to refactor this sort of code to give something more succinct. It really does become a matter of experience and preference to choose the method that is appropriate for each case.
To that end, I've listed below several options that I find serve me well:
Binding
Binding particularly within WPF gives a very powerful way of easily updating form objects. In your Xaml you apply a datacontext (generally for the form/window) and bound property for each object which then allows you to then update properties in your c# code and have them automatically reflected in the form objects.
One big advantage of this is getting all that tedious object.Text = "xyz" code out of the way.
In your given example, you could introduce a boolean property TextBoxesEnabled which is bound to the enabled property of your text boxes, and reflects whether a == b.
Domain objects
This follows on from the binding approach—in your example above it looks like all your properties are dependant of only two external pieces of data ("a" and "b"). In this situation your are often limited to doing something just like you have, where you need to set your UI properties within lots of procedural code.
However, more often you can introduce expressive domain objects that have properties that map directly to UI properties. For example, perhaps you have a User object, with a Name property, and then a user window, with a name textbox.
Now your domain object will be provided by calls into your service layer and data access infrastructure, and due to binding automatically displayed in your UI.
Code refactoring
Even where you are needing to set lots of properties directly without the ability to use more expressive objects and binding, there will often be some simple refactorings that can help.
In the code example you gave, two easy refactorings leap out to me:
a == b is a Boolean evaluation so you could have something like:
bool enableTextBoxes = a == b;
TextBox1.Enabled = enableTextBoxes;
TextBox2.Enabled = enableTextBoxes;
// etc...
You are setting the text to the same thing in the branches of the if, so take that out of the if and just have it once (though I'm guessing this is just because you were giving trivial example code).
You can loop over collections of controls, so if you need to set large numbers of control values to the same thing you can just do iterate over them and assign to each.
Assuming:
1. your controls have a pattern myControl1, myControl2, etc. (e.g textBox1, textBox2, etc)
2. your controls are all children of same FrameworkElement parent (e.g. all of them are within a Grid)
you can try something like:
bool shouldEnable = (a == b); //or whatever logic you want to have to decide the enable/disable value
for(i=0; i<10; i++)
{
string myControlName = "textBox" + i.ToString(); //assuming your pattern to be textBox1, textBox2, etc.
object myControl = myGrid.FindName(myControlName); //assuming your textboxes present in a Grid named "myGrid"
if(myControl is TextBox) //assuming your controls to be TextBoxes
{
TextBox myTextBox = (TextBox)myControl;
myTextBox.IsEnabled = shouldEnable;
myTextBox.Text = "whatever you want based on your logic";
}
}
Do remember:
1. to refer to FindName on MSDN: FrameworkElement.FindName
2. in case all of your controls are not under one parent, you might want to have a look at: How can I find WPF controls by name or type?
3. to be aware of performance implications (you may want to check it).
Also see: Find Controls by Name in WPF