I am not sure is this is correct behaviour or if its unintended. I have setup StealthFighter so that it returns a class type computed property variable called ammunition.
func globalTests() {
println("globalTests")
println("AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("MISSILES: \(myStealthFighter.missiles)")
println("AMMUNITION: \(myStealthFighter.ammunition)") // ERROR
}
class StealthFighter {
class var ammunition:Int {
return 500;
}
var missiles: Int = 5
}
When directly accessing the class StealthFighter this works fine and returns 500 as expected. But if I create and instance myStealthFighter and then try and access the class property on the instance I get the error: 'StealthFighter' does not have a member named 'ammunition' I can't find any mention of this, I am assuming from this that class properties are accessible only via the class? and not on any instances created from it? I just want to make sure I am understanding this correctly ...
EDIT:
So I have probably worded the type variable name wrong as it should probably be maxAmmunition to signify that StealthFighters can only take 500 rounds. I can see the point, if you want the maxAmmunition for the class then you ask the class.
As #Kreiri and #0x7fffffff points out it does seem that you can ask the instance what the class ammunition (or maxAmmunition) is by using dynamicType.
println("CLASS - AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("INSTA - AMMUNITION: \(myStealthFighter.dynamicType.ammunition)")
.
// OUTPUT
// CLASS - AMMUNITION: 500
// INSTA - AMMUNITION: 500
Your assumption is correct. Type variables are only meant to be accessed directly from the class. If you want to get at them from an instance, you can do so by accessing the dynamicType property on your instance, like so.
let theFighter = StealthFighter()
let missiles = theFighter.dynamicType.missiles
println(missiles)
However, I don't think that this is the correct approach for you to be taking here. Assuming that you want to have one class "StealthFighter", and possibly multiple instances of that class, each with the ability to have its own number of missiles independent of the others, you should probably make this an instance variable by simply ditching the class keyword.
dynamicType allows access instance’s runtime type as a value, so accessing class property from instance would look like this:
var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition
Works in playground, at least.
These properties are known as Type properties in swift. It should be called on its type ie class name, not on instance. Type properties holds same value across all the instances of the class just like static constant in C.
Querying and Setting Type Properties
Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type
Excerpt from : swift programming language
Swift 4:
var myStealthFighter = StealthFighter()
type(of: myStealthFighter).ammunition
Yes. This is a correct behaviour. These Type Properties can only be accessed over the Type and are not available on the instance itself.
In the Swift Book from Apple it is described in the section "Type Properties" (Page 205).
Swift Type Properties
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time"
Related
I would like to hide some property setters and initializers on my Swift model objects. These are reference data that the server provides, and under no circumstances should they be created or modified by the application. This is simple enough in Swift.
However, there is application in my project (a separate target) that needs to break this rule. It is a tool I use to populate the data in bulk, so of course needs to be able to initialize new model objects and set their properties.
What are my options for accomplishing this? I would rather not use a completely new project since it will mean a lot of code duplication. Is there some language-level way to keep this mutability hidden from one application but available to another?
If you declare a property with the let keyword. It can then only be set in the init of the type.
You can also declare a private setter to make the property readonly from the caller of the type but read/write inside the type
struct Foo {
private(set) var bar: Bool = true
func toggle() {
bar.toggle()
}
}
var foo = Foo()
let barState = foo.bar // This works
foo.toggle() // This works too
foo.bar.toggle() // This will make a compile time error
Let's started with the code snippet:
St Foo {
var proA: Int = 0 { // needs initialization
willSet {
print("about to set proA to \(newValue) from \(proA)")
}
didSet {
print("already set proA to \(proA) from \(oldValue)")
}
}
var ProB: Int { // do not needs initialization
return 1
}
}
let foo = Foo()
foo.proA = 23
print(foo.ProB)
Here are some of my personal understandings about the the stored and computed property:
a: Property with only the observer (willSet and didSet) is not a computed property but a stored property (ex. the proA property in the code above).
b: Computed property must not has initialization (See the comments of the code above).
c: setter is kind of equal to the property observer, the property observer is just the setter + the observer to of the before and after mutating.
Questions:
1. I wonder what makes a property a computed property? Is it correct that as long as the property has a getter and return it is a computed property?
2. Are all my understandings (a, b & c) correct? If not, would be nice of you to point out.
3. Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
Thanks a lot.
First, this is about variables, not properties. Any variable can be a computed variable. A property is just one way to use a variable.
I think on the whole you are making a big mistake in putting a stored variable with setter observers side by side with a computed variable. They are unrelated!
Think of a computed variable as something that looks and acts like a variable when you use it — you get and (maybe) set it — but is in fact a function (or a pair of functions). It is just a compact way of calling a function. That's all it is.
A stored variable with observers, on the other hand, is just a stored variable that also has some observers.
Okay, on to your questions:
I wonder what makes a property a computed property? Is is correct that as long as the property has a getter and return it is a computed property?
Yes. It's a computed variable because you declared it using the syntax that makes it a computed variable (with the curly braces).
Are all my understandings (a, b & c) correct? If not would be nice of you to point out
Yes. I think your "c" is quite insightful: a computed variable does not need a setter observer because it has (gasp!) a setter!
Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
There is no sense in which a computed variable "has" a value — it is computed! it's just some functions! — so it makes no sense to assign it an "initial" value.
A stored property is a property of which the property value is stored together with the instance of the class or struct. The value may be changed, but the property can also be a constant. Thus a stored property can be as simple as:
var proA: Int
let proB: Int
var proC: Int = 0
Computed properties do not store a value. Thus you cannot assign a value to a computed property. A Computed property should have a getter that returns a value. I a broad term, you can think of a computed property as a property that returns the value of a function.
Example of Computed Property
var proA: Int {
return proB * proC
}
With regards to your questions:
Computed Property is therefor a property that do not store a value, and contains a get to return the 'computed' value of the property.
a is correct, b computed properties should not have initialization, c if you mean willSet and didSet. Yes they are like observers for when the property's value will change and did change respectively
Since the value of a computed property is not stored and will never be used, the compiler forbids it.
Hope this helps a bit.
I wonder what makes a property a computed property? Is is correct that as long as the property has a getter and return it is a computed property?
If you define get { } inside the property declaration, it makes that property to a computed property.
And it cannot have initial value as when you access the property, it will always call get{} function declared in property.
Are all my understandings (a, b & c) correct? If not would be nice of you to point out
a is correct
b is wrong.
You can not set initial value for computed property.
Because as I explained in question 1, it will always return result of get{} when you need access to the property.
c : 50% right
setter , it can also be used as to store newValue into another private variable and you can do some additional observing logic. So to observe value changes on stored property, you use willSet and didSet
You can define observing logic on computed property (which has getter and setter) on set{} declaration. But main purpose of set {} is to store the value to another variable or for example UserDefaults.
Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?
Same answer
Your code makes compiler to be confused
When you set initial value on the property on declaration, the compiler tries to understand it as stored property. But you also defined get{} for this property, and it means it is computed property and should always return 22 when you access the property. So you should remove one of two.
a. Yes,a property with only observer is a stored property not a computed property.Beacuase property observer tracks the value of a property whose value has initialised previously & it's now changing ,that's a stored property. It's not applicable for a computed property since it has no predefined value
b. computed property is a property whose value depends on other variables, we should declare only those properties as computed property , who needs to be computed using value of another variables ,so it's value cannot be initialised in advance.
for e.g. - If we have 2 variables a & b. we need their addition value , so a variable named 'sum' is used , then sum will be declared as a computed property & its get{} block will return (a+b) that's sum of a & b & the value of sum variable.Then in this case we can't initialise property 'sum'
in advance because it will be computed using a & b.
c. Setter is not an observer it sets value of another variable or performs some actions related to other variables whereas a property observer tracks changes in value of its associated variable itself. for e.g. it's meaningless to use a property observer for variable 'sum' as described in point b .
I have a object property in my Class which is private and marked as read-only.
private var readOnlyObj:Object;
I can only access it with a get method:
public function get readOnly(){ return readOnlyObj }
I can access it by:
var objClass = new MyClass();
trace(objClass.readOnly)
And if i'll try to modify it:
objClass.readOnly = new Object();
I'll get an error:
Error# Property is read only.
Now my question is:
How do I set the properties of my readOnlyObj as read-only?
If I have set the object in the constructor:
readOnlyObj["property1"] = 0;
And modify that property by:
objClass.readOnly["property1"] = 2;
It is valid. I want set the property1 to a read-only property. Is this possible? Thank You!
You can do this by returning a duplicate of the original object and not the object itself.
The transform properties of DisplayObjects work like this: you can get the object property from a get function and can modify the object, but such modification has no effect until you pass the modified object back to the set function.
In your case, there's no way to give the object back (no setter) and by returning a copy (commonly called 'clone') from the getter, there is no way to modify the object property from outside, because the returned reference reference the newly created independent clone, essentially making the internal object constant.
What you are asking is not possible and only yield the answer "no" if on the other hand you asked about how to achieve that functionality then there would be a few answer possible.
First of all given your code and the problem at hand it is clear that you misunderstand the class scope. You set:
private var readOnlyObj:Object;
As read only while it's really not the object you want to protect, it's its properties. So readOnlyObj should really not even be visible and accessible.
Now that readOnlyObj is private and not accessible, you can put together a simple method to retrieve properties:
public function getProperty(name:String):*
{
if(readOnlyObj[name] != undefined)
{
return readOnlyObj[name];
}
return null;
}
It might also be useful to know how to put together a public setter that cannot be used externally.
Create an internal Boolean variable (only with true package), then internally set that variable to true before setting the property then set it back to false. Since externally that boolean cannot be set you end up with a public setter that cannot be used externally.
internal var allowSetter:Boolean;
public function set whatever(value:*):void
{
if(allowSetter)
{
//set property ect...
allowSetter = false;
}
}
You can't really do this, at least in the way you describe. You can of course make your readOnly object a custom class instance that only has read-only properties, but you can't freeze a dynamic Object instance.
I am starting studying OOP and I want to learn what constitutes a class. I am a little confused at how loosely some core elements are being used and thus adding to my confusion.
I have looked at the C++ class, the java class and I want to know enough to write my own pseudo class to help me understand.
For instance in this article I read this (.. class attribute (or class property, field, or data member)
I have seen rather well cut out questions that show that there is a difference between class property and class field for instance What is the difference between a Field and a Property in C#?
Depending on what language I am studying, is the definition of
Property
Fields
Class variables
Attributes
different from language to language?
"Fields", "class variables", and "attributes" are more-or-less the same - a low-level storage slot attached to an object. Each language's documentation might use a different term consistently, but most actual programmers use them interchangeably. (However, this also means some of the terms can be ambiguous, like "class variable" - which can be interpreted as "a variable of an instance of a given class", or "a variable of the class object itself" in a language where class objects are something you can manipulate directly.)
"Properties" are, in most languages I use, something else entirely - they're a way to attach custom behaviour to reading / writing a field. (Or to replace it.)
So in Java, the canonical example would be:
class Circle {
// The radius field
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// The radius property
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
// We're doing something else besides setting the field value in the
// property setter
System.out.println("Setting radius to " + radius);
this.radius = radius;
}
// The circumference property, which is read-only
public double getCircumference() {
// We're not even reading a field here.
return 2 * Math.PI * radius;
}
}
(Note that in Java, a property foo is a pair of accessor methods called getFoo() and setFoo() - or just the getter if the property is read-only.)
Another way of looking at this is that "properties" are an abstraction - a promise by an object to allow callers to get or set a piece of data. While "fields" etc. are one possible implementation of this abstraction. The values for getRadius() or getCircumference() in the above example could be stored directly, or they could be calculated, it doesn't matter to the caller; the setters might or might not have side effects; it doesn't matter to the caller.
I agree with you, there's a lot of unnecessary confusion due to the loose definitions and inconsistent use of many OO terms. The terms you're asking about are used somewhat interchangeably, but one could say some are more general than others (descending order): Property -> Attributes -> Class Variables -> Fields.
The following passages, extracted from "Object-Oriented Analysis and Design" by Grady Booch help clarify the subject. Firstly, it's important to understand the concept of state:
The state of an object encompasses all of the (usually static) properties of the object plus the current (usually dynamic) values of each of these properties. By properties, we mean the totality of the object's attributes and relationships with other objects.
OOP is quite generic regarding certain nomenclature, as it varies wildly from language to language:
The terms field (Object Pascal), instance variable (Smalltalk), member object (C++), and slot (CLOS) are interchangeable, meaning a repository for part of the state of an object. Collectively, they constitute the object's structure.
But the notation introduced by the author is precise:
An attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class. Using the language-independent syntax, an attribute may have a name, a class, or both, and optionally a default expression: A:C=E.
Class variable: Part of the state of a class. Collectively, the class variables of a class constitute its structure. A class variable is shared by all instances of the same class. In C++, a class variable is declared as a static member.
In summary:
Property is a broad concept used to denote a particular characteristic of a class, encompassing both its attributes and its relationships to other classes.
Attribute denotes a part of an aggregate object, and so is used during analysis as well as design to express a singular property of the class.
Class variable is an attribute defined in a class of which a single copy exists, regardless of how many instances of the class exist. So all instances of that class share its value as well as its declaration.
Field is a language-specific term for instance variable, that is, an attribute whose value is specific to each object.
I've been doing oop for more than 20 years, and I find that people often use different words for the same things. My understanding is that fields, class variables and attributes all mean the same thing. However, property is best described by the stackoverflow link that you included in your question.
Generally fields, methods, static methods, properties, attributes and class (or static variables) do not change on a language basis... Although the syntax will probably change on a per language basis, they will be function in the way you would expect across languages (expect terms like fields/data members to be used interchangably across languages)
In C#....
A field is a variable that exists for a given instance of a class.
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field
protected int GetField
{
get
{
return _field;
}
}
}
Fields have a "visibility" this determines what other classes can see the field, so in the above example a private field can only be used by the class that contains it, but the property accessor provides readonly access to the field by subclasses.
A property lets you get (sometimes called an accessor) or set (sometimes called a mutator) the value of field... Properties let you do a couple of things, prevent writing a field for example from outside the class, change the visibility of the field (eg private/protected/public). A mutator allows you to provide some custom logic before setting the value of a field
So properties are more like methods to get/set the value of a field but provide more functionality
eg.
public class BaseClass
{
// This is a field that might be different in each instance of a class
private int _field;
// This is a property that accesses a field, but since it's visibility
// is protected only subclasses will know about this property
// (and through it the field) - The field and property in this case
// will be hidden from other classes.
protected int GetField
{
// This is an accessor
get
{
return _field;
}
// This is a mutator
set
{
// This can perform some more logic
if (_field != value)
{
Console.WriteLine("The value of _field changed");
_field = value;
OnChanged; // Call some imaginary OnChange method
} else {
Console.WriteLine("The value of _field was not changed");
}
}
}
}
A class or static variable is a variable which is the same for all instances of a class..
So, for example, if you wanted a description for a class that description would be the same for all instance of the class and could be accessed by using the class
eg.
public class BaseClass
{
// A static (or class variable) can be accessed from anywhere by writing
// BaseClass.DESCRIPTION
public static string DESCRIPTION = "BaseClass";
}
public class TestClass
{
public void Test()
{
string BaseClassDescription = BaseClass.DESCRIPTION;
}
}
I'd be careful when using terminology relating to an attribute. In C# it is a class that can be applied to other classes or methods by "decorating" the class or method, in other context's it may simply refer to a field that a class contains.
// The functionality of this attribute will be documented somewhere
[Test]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
}
}
Some languages do not have "Attributes" like C# does (see above)
Hopefully that all makes sense... Don't want to overload you!
Firstly, you need to select a language. For example, I would recommend you to select Ruby language and community. Until you select a language, you cannot escape confusion, as different communities use different terms for the same things.
For example, what is known as Module in Ruby, Java knows as abstract class. What is known as attributes in some languages, is known as instance variables in Ruby. I recommend Ruby especially for its logical and well-designed OOP system.
Write the following in a *.rb file, or on the command line in irb (interactive Ruby interpreter):
class Dog # <-- Here you define a class representing all dogs.
def breathe # <-- Here you teach your class a method: #breathe
puts "I'm breathing."
end
def speak # <-- Here you teach your class another method: #speak
puts "Bow wow!"
end
end
Now that you have a class, you can create an instance of it:
Seamus = Dog.new
You have just created an instance, a particular dog of class Dog, and stored it in the constant Seamus. Now you can play with it:
Seamus.breathe # <-- Invoking #breathe instance method of Seamus
#=> I'm breathing.
Seamus.speak # <-- Invoking #speak instance method of Seamus
#=> Bow wow!
As for your remaining terminology questions, "property" or "attribute" is understood as "variable" in Ruby, almost always an instance variable. And as for the term "data member", just forget about it. The term "field" is not really used in Ruby, and "class variable" in Ruby means something very rarely used, which you definitely don't need to know at this moment.
So, to keep the world nice and show you that OOP is really simple and painless in Ruby, let us create an attribute, or, in Ruby terminology, an instance variable of Dog class. As we know, every dog has some weight, and different dogs may have different weights. So, upon creation of a new dog, we will require the user to tell us dog's weight:
class Dog
def initialize( weight ) # <-- Defining initialization method with one argument 'weight'
#weight = weight # <-- Setting the dog's attribute (instance variable)
end
attr_reader :weight # <-- Making the dog's weight attribute visible to the world.
end
Drooly = Dog.new( 16 ) # <-- Weight now must provide weight upon initialization.
Drooly.weight # <-- Now we can ask Drooly about his weight.
#=> 16
Remember, with Ruby (or Python), things are simple.
I discovered in my question that Properties as defined in .Net are just a convenience syntax for code, and they are not tied to underlying variables at all (except for Auto-Implemented Properties, of course). So, saying "what is the difference between class property and class field" is like saying: what is the difference between a method and an attribute. No difference, one is code and the other is data. And, they need not have anything to do with each other.
It is really too bad that the same words, like "attribute" and "property", are re-used in different languages and ideologies to have starkly different meanings. Maybe someone needs to define an object-oriented language to talk about concepts in OOP? UML?
In The Class
public class ClassSample
{
private int ClassAttribute;
public int Property
{
get { return ClassAttribute; }
set { ClassAttribute = value; }
}
}
In the Program
class Program
{
static void Main(string[] args)
{
var objectSample = new ClassSample();
//Get Object Property
var GetProperty = objectSample.Property;
}
}
I try to inherit a gobject and, among other things, would like to change the value of a G_PARAM_CONSTRUCT_ONLY property so the next child class doesn't have to care.
Here's an example to depict this: GtkComboBox has a construct only property called "has-entry" with default value FALSE. In class A I want to change this value to TRUE, so that class B doesn't need to care.
GtkComboBoxClass <-- AClass <-- BClass
"has-entry" FALSE TRUE
The first naive approach was to use g_object_set() in A's instance_init function, but to no avail.
The next idea was to obtain the GParamSpec with g_object_class_find_property() and change the default value with g_param_value_set_default() in A's class_init function. But I suppose this to change the default for all GtkComboBoxClass derived objects.
The best idea I could come up with: If g_object_class_override_property() creates a new GParamSpec I could find this and set its default value in A's class_init function. But documentation doesn't loose a word about this.
So my question: Is this a working, and intended, way of accomplishing this, or is there a better solution?
Tried so far:
g_object_set() in instance init():
no warning on start
no effect
g_object_set() in GObjectClass->constructor():
no warning on start
no effect
warning on exit: invalid cast from GtkCellCiew to GtkEntry
g_object_set() in GObjectClass->constructed():
warning on start: can't be set after construction
Thanks
Stefan
if you want to set a property in a sub-class, and that property is construct-only, then you should use the constructed virtual function to call g_object_set() instead of the init virtual.
properties marked as construct-only will be applied during construction, using their default value, unless specified on the constructor itself — i.e. with g_object_new(). this means that setting a construct-only property inside init() will not suffice, as the value will be set after init() has been called. the constructed() virtual function, on the other hand, is called after the constructor properties have been applied, so it's possible to override the default value there.
Answering this for myself:
A look into gobject source reveals that the properties list given to constructor() contains all G_PARAM_CONSTRUCT and G_PARAM_CONSTRUCT_ONLY properties and their default or given values.
Modifying these values is undocumented (or at least I couldn't find it), but it works.
Construction time property values have to be modified in this list before chaining up to parents constructor, non construct properties have to be set afterwards. Example code looks like:
static GObject *constructor(GType gtype, guint n_properties, GObjectConstructParam *properties) {
GObject *object;
guint i;
gchar const *name;
GObjectConstructParam *property;
for (i = 0, property = properties; i < n_properties; ++i, ++property) {
name = g_param_spec_get_name(property->pspec);
if (!strcmp(name, "has-entry")) // is G_PARAM_CONSTRUCT_ONLY
g_value_set_boolean(property->value, TRUE);
}
object = G_OBJECT_CLASS(parent_class)->constructor(gtype, n_properties, properties);
g_object_set(object, "entry-text-column", TEXT_COLUMN, NULL);
return object;
}