I have a simple class structure like so:
classdef super < hgsetget
properties(Constant = true, Access = private)
PROP1 = 1;
PROP2 = {2 [3 4] [5 6]};
end
methods
function self = super()
// Constructor code here
// ...
end
end
end
which is then inherited by a subclass like so.
classdef sub < super
properties
PROP3 = 7;
end
methods
function self = sub()
// Subclass constructor here
// ...
self = self#super();
test = self.PROP1; // I don't appear to have access to PROP1 from Super
end
end
end
My issue is when I try to access to the super's property PROP1 or PROP2 I don't seem to get access:
No appropriate method, property, or field PROP1 for class sub.
Is there a way to access to the super's property within Matlab?
In superclass super set properties attributes to
properties(Constant = true, Access = protected)
From the documentation an access attribute determines what code can access these properties:
public — Unrestricted access
protected — Access from methods in class or subclasses
private — Access by class methods only (not from subclasses)
You define the properties as private, those are not inherited.
Use Access = protected instead.
Related
I would like to start that I don't want a to hear about how expensive and terrible reflection is. That won't help—I have a very good reason to use reflection and that's not my question.
Specifically, I have a class within a class that contains several static properties of the same type.
Public Class Foo
Public Class Bar
Public Shared Property prop1 As New CustomClass()
Public Shared Property prop2 As New CustomClass()
Public Shared Property prop3 As New CustomClass()
End Class
End Class
Public Class CustomClass
Public Sub DoStuff()
End Sub
End Class
I'm looking to create a method in Foo that calls DoStuff on each of the properties contained within it. How can I do this? Here's the general idea of what I want to include in Foo, but I obviously can't convert PropertyInfo to CustomClass:
Private Sub Example()
For Each prop As PropertyInfo In GetType(Foo.Bar).GetProperties()
DirectCast(prop, CustomClass).DoStuff()
Next
End Sub
How can I get the static properties and cast them to CustomClass objects?
PropertyInfo represents the type's property get/set method pair. To evaluate the getter you simply call GetValue, like so:
(in C# because I'm a language snob)
foreach( PropertyInfo pi in typeof(Foo.Bar).GetProperties() ) {
// Use null as arguments because it's a static property without an indexer.
Object got = pi.GetValue( null, null );
CustomClass got2 = got as CustomClass;
if( got2 != null ) {
Console.WriteLine( got2.ToString() );
}
}
And to convert Dai's answer to VB because I'm not a language snob:
For Each pi As System.Reflection.PropertyInfo in Foo.Bar.GetType.GetProperties()
' Use nothing as arguments because it's a shared property without an indexer.
Dim got = pi.GetValue(Nothing, Nothing)
Dim got2 as CustomClass = DirectCast(got, CustomClass)
If Not IsNothing(got2) Then Console.WriteLine(got2.toString())
Next
huzzah for less lines and more keystrokes...
In Swift, what is the conventional way to define the common pattern where a property is to be externally readonly, but modifiable internally by the class (and subclasses) that own it.
In Objective-C, there are the following options:
Declare the property as readonly in the interface and use a class extension to access the property internally. This is message-based access, hence it works nicely with KVO, atomicity, etc.
Declare the property as readonly in the interface, but access the backing ivar internally. As the default access for an ivar is protected, this works nicely in a class hierarchy, where subclasses will also be able to modify the value, but the field is otherwise readonly.
In Java the convention is:
Declare a protected field, and implement a public, read-only getter (method).
What is the idiom for Swift?
Given a class property, you can specify a different access level by prefixing the property declaration with the access modifier followed by get or set between parenthesis. For example, a class property with a public getter and a private setter will be declared as:
private(set) public var readonlyProperty: Int
Suggested reading: Getters and Setters
Martin's considerations about accessibility level are still valid - i.e. there's no protected modifier, internal restricts access to the module only, private to the current file only, and public with no restrictions.
Swift 3 notes
2 new access modifiers, fileprivate and open have been added to the language, while private and public have been slightly modified:
open applies to class and class members only: it's used to allow a class to be subclassed or a member to be overridden outside of the module where they are defined. public instead makes the class or the member publicly accessible, but not inheritable or overridable
private now makes a member visible and accessible from the enclosing declaration only, whereas fileprivate to the entire file where it is contained
More details here.
As per #Antonio, we can use a single property to access as the readOnly property value publicly and readWrite privately. Below is my illustration:
class MyClass {
private(set) public var publicReadOnly: Int = 10
//as below, we can modify the value within same class which is private access
func increment() {
publicReadOnly += 1
}
func decrement() {
publicReadOnly -= 1
}
}
let object = MyClass()
print("Initial valule: \(object.publicReadOnly)")
//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1
object.increment()
print("After increment method call: \(object.publicReadOnly)")
object.decrement()
print("After decrement method call: \(object.publicReadOnly)")
And here is the output:
Initial valule: 10
After increment method call: 11
After decrement method call: 10
In my VB.Net code, I know that when I declare a property in a class I can do so using the shorthand of, for example, Public Property Prop1 As String and .Net automatically creates a private variable _Prop1 that I can refer to within my class.
I also know that I can refer to that variable within my code using either _Prop1 or by Prop1.
Now since I've always assumed that the preferred method is to use the private variable, I've always tried to make modifications / write code within my class referring to _Prop1. This is where my problem now comes in...
I have the following situation:
Public Class MyClass_Base
Public Overridable Property Prop1 As String = "val1"
Public Sub Test()
If _Prop1 = ....
End Sub
End Class
Public Class MyClass
Inherits MyClass_Base
Public Overrides Property Prop1 As String = "val2"
End Class
Basically, I define the property as Overridable in my base class, now when I get to the Test() subroutine, _Prop1 has the value of Nothing. However Prop1 has the correct value of val2.
Programming gurus out there, what is the correct way to deal with this situation?
Do I ignore the auto-created prive variable _Prop1 and work with the public Prop1 or is there something else I should add in / not even use the shorthand notation for this and write my own getter / setter logic to ensure things change as I would like?
Thanks!!!
I think you've answered your own question. You should absolutely not rely on hidden compiler mechanics in your own code. You're referencing a variable that you did not declare and there is no guarantee in the framework that this variable will be there (or work as you might expect, as you've discovered) - it's a hack to use it, so don't.
Unless you have a very good reason not to, code in the class should reference the public property just the same as code using the class would. If you're using automatic properties then there is no difference between doing that and using the private variable. It also has the benefit that if you do, at a later time, decide to implement explicit getters and setters that your code does not break and that your new getters and setters get called.
To explore the reason you get the unexpected result, in declaring
Public Overrides Property Prop1 As String = "val2"
You end up with two different _Prop1 variables - MyClass_Base._Prop1 and MyClass._Prop1. When you then call Test(), you are calling the base class method and that will refer to the base class's _Prop1 variable which has not been set to anything since you have overriden the implicit variable, getter, and setter in the subclass.
To illustrate the point, this is similar to :
Public Class MyClass_Base
Private _Prop1 As String = "val1"
Public Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
Public Class MySubClass
Inherits MyClass_Base
Private _Prop1 As String = "val2"
End Class
Sub Main()
Dim class1 As New MyClass_Base
Dim class2 As New MySubClass
class1.Test()
class2.Test()
End Sub
Where your output will be :
val1
val1
In the above case MyClass_Base._Prop1 is always initialized, however, while in your case, it is not. In either case, the Test() method belongs to the base class so it will always refer to its own _Prop1 and not any variables of the same name declared in subclasses.
If you do need to refer to the private field, for whatever reason, you have to be very careful about how you do it (and the implications that follow). Any method that does so would need to itself be Overridable if subclasses are intended to work with their own private variables in the same way. Not to suggest that you should continue to use implicit variables, but to demonstrate :
Public Class MyClass_Base
Public Overridable Property Prop1 As String = "val1"
Public Overridable Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
Public Class MySubClass
Inherits MyClass_Base
Public Overrides Property Prop1 As String = "val2"
Public Overrides Sub Test()
Console.WriteLine(_Prop1)
End Sub
End Class
Here we get the "expected" result because MySubClass overrides test to reference its own private field. Better to just stick to using the property names.
From the documentation on Auto Implemented Properties:
"Attributes specified for the property do not apply to the backing field."
This is one of those areas where C# and VB.NET need to be aligned.
C# (correctly) does not allow you to access the auto implemented property backing field (without some convoluted work). I honestly don't know what you can access this in VB.
So the rule here is even though you can access the backing field of an auto implemented property you really shouldn't modify this directly (nor should you need to)
If you need to then you should use a defined backing field (with initialisation) and explicit Get and Set
Is there a way to have one variable per class in vbscript?
If not what is the best way to emulate it? Prefixing a global variable declared next to the class?
Also is there a way to declare static/class methods(for a static constructor) or am I force to prefix a function?
In languages that support class-level/static data or methods you can
associate/bind data or methods explicitly to the set of objects defined by the class. So you can have Customer.Count and Product.Count and a plain Count (or ##Count) in Customer code will access the right number.
use such data or method without having an instance of the class (yet).
VBScript does not support static data or methods. You have to use global data or functions/subs and do the associating in your mind (perhaps with a little help from a naming convention). Accessing these 'static'=global elements without an object is trivial, but - obviously - should be done with care.
You can embed one or more singleton objects or code references (GetRef()) in your objects to bind them closer to the class, but that will increase the size of the instances.
You can do something like this to sort of emulate a static class:
Class Defines_
Public Sub DoSomethingUseful
End Sub
End Class
Dim Defines : Set Defines = New Defines_
...
Defines.DoSomethingUseful
This can be used to give you something analogous to constructors (really, factory methods):
Class Something
Private mValue
Public Property Get Value : Value = mValue : End Property
Public Property Let Value(x) : mValue = x : End Property
End Class
Class SomethingFactory_
Public Function Create(value)
Set Create = New Something
Create.Value = value
End Function
End Class
Dim SomethingFactory : Set SomethingFactory = New SomethingFactory_
...
Dim something : Set something = SomethingFactory.Create(5)
I would like to define an interface with properties in an abstract class like this
classdef A
properties (Abstract = true)
Valid;
end
end
with an implementation of this interface like this
classdef B < A
properties (Dependent = true)
Valid;
end
methods
function v = get.Valid(obj)
v = 1;
end
end
end
but when I try to make an instance of B I get the following error
>> c = B()
??? Error using ==> B
The property 'Valid' restriction defined in class 'B' must match the property definition in base class 'B'.
Can anyone tell me what I doing wrong?
Try setting the Dependent property attribute in the base class as well:
classdef A
properties (Abstract = true, Dependent = true)
Valid;
end
end
According to the documentation:
Concrete subclasses must redefine abstract properties without the
Abstract attribute set to true
The way I understood this, subclass property attributes must match the base class (without the Abstract property)