Using getters and setters is a very well known practice in object oriented languages. This is done in order to have a greater control on the variables. To achieve this, we make the variables private in java and hence we need both getters and setters there.
But in kotlin this is not the case. Here even public variables are accessed through getters and setters by default. Though setters can be used to validate an assignment to a variable, getters just return the variable as it is stored (and I think this is it for them). Hence custom getters are not required at all.
I have also seen some wrong usage of this feature where instead of writing a zero argument function, they use a val and do the computation in the getter. This creates an illusion that the thing is just a val but in reality it does not store anything and instead it performs a computation every time.
So is there a real need to have a custom getter?
getters just return the variable as it is stored (and I think this is it for them). Hence custom getters are not required at all.
If that was really the case, why have getters at all in Java? One of the goals of encapsulation is to make sure a change in the class doesn't change it's API. It's the same in Kotlin.
I have also seen some wrong usage of this feature where instead of writing a zero argument function, they use a val and do the computation in the getter. This creates an illusion that the thing is just a val but in reality it does not store anything and instead it performs a computation every time.
This is a perfectly valid use case for a custom getter. In Kotlin, one must not assume that using a property is entirely free of overhead. There are many questions to ask yourself when choosing between a property with a getter or a zero-arg function:
Does it describe behavior? Use a function (walk(), build(), etc)
Does it describe state? Use a property (firstName, lastIndex, etc)
Additionally, a property getter should not throw an exception, should be either cheap to calculate or cached on first access, and should return the same result for multiple consecutive executions. Here's examples from the standard library:
ArrayDeque.first() is a function, it throws if deque is empty.
List.lastIndex is a property, it's cheap to calculate.
Lazy<T>.value is a property, the value is computed and cached on first access.
Most delegated properties make use of custom getters.
More reading:
Why use getters and setters/accessors?
Kotlin: should I define Function or Property?
Just some more info. Other than readability, the possibility of defining a custom getter allows you to evolve a class without changing its public members, even if you started with a simple val with no custom getter.
In a language without properties like Java, if you define a public field:
public class Foo {
public final int value;
public Foo(int value) {
this.value = value;
}
}
And then later you want to modify the class to add a feature where it returns negated values if you flip a Boolean, there's no way to do it without breaking code that uses the original version of the class. So you should have used getters and setters to begin with.
But in Kotlin, you can't directly expose a backing field like this, so it's impossible to paint yourself in a corner like you could with a public field in Java. If your original class is like this:
class Foo(val value: Int)
You could modify it like this to add the feature and have no impact on code that already uses the class.
class Foo(private val originalValue: Int) {
var isNegated = false
val value: Int
get() = if (isNegated) -originalValue else originalValue
}
Related
enum class Admin(myName:String, val id:Int, val age:Int){
ROOT_ADMIN ("Pete", 1, 55),
ACADEMIC_ADMIN("Jacob",11,56),
DEPARTMENT_ADMIN("Robin",111,50),
CLASS_ADMIN("Chris",1111,22)
To access the properties of objects of enum class Admin, when I type
Admin.CLASS_ADMIN.____
Naturally, myName to come out in the IDE auto-complete is expected. But its not happening. But id and age does come as they have val keyword associated with them.
But when I add var in front of myName, like:
enum class Admin(var myName:String, val id:Int, val age:Int)
I am now getting myName in auto-complete.
What is the importance of var keyword here?
Note: I am aware of the fact that when we declare variables with var or val keywords in constructor, it declares a property inside that class.
But how this logic relates to this situation?
This is more about Kotlin properties and less about how val/var work with enums. In fact for most of this answer, we can completely ignore the fact that we're even talking about enums, as opposed to any other Kotlin class (but I do have a note at the end on this).
For background, when you create an instance of a class in Kotlin and provide arguments to its constructor, if those arguments have var or val, Kotlin will treat them as properties. If not, it treats them as an argument to the constructor (these can be used in init blocks, for example but do not get turned into properties).
That's what is happening in your case. Kotlin treats myName as a constructor argument and effectively throws it away as you aren't using it. It does not get turned into a property. For id and age, you've specified they are val, so Kotlin turns them into read-only properties.
As for var, when Kotlin sees this it makes them into a read/write property (they can change).
Basically: Kotlin turned id and age into read-only properties and myName was defined as a constructor argument. This is why autocomplete did not offer you myName, it wasn't a property.
Some general advice: I would absolutely not declare any mutable properties on an enum (so, use val only for read-only properties). By using var, you'll get mutable read/write properties. Normally that's fine but with enum specifically there is an expectation that they do not change, ever. You are declaring a fixed set of values (an enumeration of them!) whose internal properties do not change. As a developer if I saw an enum whose internal state was mutable, it would immediately seem wrong.
Since item of enum class is acting like object in Kotlin (just for understanding), if you declare property as var of enum class, you could change the property value and it affects everywhere. This might be hard to understand. You can see below example code.
enum class Test(var a: String) {
A("a"),
B("b");
}
fun main()
{
println(Test.A.a) // a
Test.A.a = "b"
println(Test.A.a) // b
}
Usually, you might not want to declare a property as mutable for the design.
I need to get and set a property of another class from a method and therefore need to pass in either the property reference of lambdas for the getter and the setter:
Passing in the property reference
otherInstance::property
Passing in a lambda for the getter and one for the setter:
{otherInstance.property} // getter
{value -> otherInstance.property = value} // setter
I like the first one, because for me the code is easier to read and shorter, but my alarm bells ring when I read about it on the official documentation, because of the term "reflection". My knowledge from Java is that reflection generally isn't a good thing. Is that also valid with Kotlin? Is it valid with this case? Is one of both ways (property reference or lambdas) more performant or more safe?
By using KMutableProperty0 you would technically be exposing an object that can be used for reflection. If you want to be strict about avoiding reflection, you could use the separate function references for the getter and setter. Note that it's not necessary to pass a lambda as a function reference to a higher-order function. The compiler can interpret property references as functions if the effective signature matches. This would unfortunately mean having to pass the property reference twice. Unfortunately, the setter has to be retrieved via what is technically reflection in this case:
class Test (var x: Int)
fun foo(getter: () -> Int, setter: (Int) -> Unit) {
//...
}
val test = Test(1)
foo(test::x, test::x.setter)
// Zero reflection call:
foo(test::x) { test.x = it }
At some point you have to question how badly you want to avoid reflection, because the above code looks very messy to me. If your class takes a KMutableProperty0 reference, it is much simpler to use. As long as your receiving function isn't using the reference to introspect the code, and only calls get() or set() on it, you are not really using reflection in the ways that are suggested should be avoided.
fun foo(property: KMutableProperty0<Int>) {
//...
}
val test = Test(1)
foo(test::x)
The documentation is about Member references and reflection,
If you are referring to Property references which isn't using reflection itself,
Reflection is only referred in different section Obtaining member references from a class reference
dynamically inspect an object to see e.g. what properties and functions it contains and which annotations exist on them. This is called reflection, and it's not very performant, so avoid it unless you really need it.
Kotlin has got its own reflection library (kotlin-reflect.jar must be included in your build). When targeting the JVM, you can also use the Java reflection facilities. Note that the Kotlin reflection isn't quite feature-complete yet - in particular, you can't use it to inspect built-in classes like String.
This question is about OOP design.
What are the advantages/disadvantages of passing all arguments to class constructor vs passing arguments to member functions ?
In my case I know all arguments in the beginning of the program and I don't need to change them until the program is over.
In C++ the situation would be something like that (although in my code I need to parse more arguments and the member functions are more complex):
// All arguments in class constructor
Rectangle::Rectangle(float base, float height, string rectColor){
this->area = 0;
this->base = base;
this->height = height;
this->rectColor = rectColor;
}
void Rectangle::calcArea(){
area = base * height;
}
void Rectangle::paintRectangle(){
// use area
// whatever
}
vs
// Arguments in member functions
Rectangle::Rectancle(){
this->area = 0;
}
void Rectangle::calcArea(float base, float height){
area = base * height;
}
void Rectangle::paintRectangle(string rectColor){
// use area
// whatever
}
One strategy that I'm using is: If I need the variable in multiple member functions I make it a class variable. Is that good or the best approach ?
A bad thing about passing everything into constructor is that it would have lots of arguments. And also I wouldn't need to call the class member functions in my main.
Please explain the main principles I should follow.
Benefits for putting arguments in the constructor:
The instance is more completely initialized (no problems with the order of functions to be called to get a 'complete'useful instance.
Benefits for putting arguments to specific functions:
More flexibility, since the functions use variables instead of 'constants' passed to the constructor
The arguments passed to functions tend to belong better to the functions (e.g. for paintRectangle it is logical to pass the color, but if it never change, why making the flexibility to change the color afterwards?)
To prevent too many arguments in the cnstructor
Create a structure to pass the variables
Create a sub class ... if you need more than 5-7 parameters, possibly the responsibility of the class is too big.
Use named arguments (more clearer, but still the same amount of arguments)
In general, make classes as limited as possible, do not make them more flexible than needed UNLESS you know beforehand the functionality is needed at a later stage.
The one of the most important thing about constructors is that they make your OOP code consistent. For any object, it is good approach, if you already know, that someone created with properties need to have to exist.
i.e. Rectangle cannot exist without "height".
Therefore the "minimum parameters constructor" is great advantage. (the minimum required parameters need to have for object, to be usable and for not able to crash, when computing i.e. area)
If you have more parameters, that they are not neccesary, it is good to create more constructors based on what is probably "often use" of your object.
I am new to OOP. I am still in a learning phase.
Why do we need constructors, When we can initialize the values of the properties (variables) by writing a "Initialize function"?
Basically why do we write a constructor when we can achieve the same results even by writing a function for initializing the variables?
The constructor IS the "Initialize function"
Rather than calling two functions
object = new Class;
object.initialize();
You just call
object = new Class();
The logic inside the constructor can be identical to the logic inside the initialize function, but it's much tidier and avoids you naming your function initialize(), me naming mine initialize_variables(), and someone else naming theirs init_vars()... consistency is useful.
If your constructor is very large, you may still wish to split variable initialisation into a separate function and calling that function from your constructor, but that's a specific exception to the scenario.
So answer is simple
Why do we write Constructor?
Because in C you can write,
int i;
if write like this In above case data type and variable defines if you define like this memory allocated for i variable.So simple here we define class name and variable name(object name) we can create memory allocated for class name.
Example
myClass objectName;
But in C++ new keyword is used for dynamic memory allocation, so this dynamic memory which we can allocate to our class but here my example myClass is our class and we want to allocate to dynamic memory allocated.
So
myClass objectName = new myClass();
and simply constructor is memory allocation for class variable is called the constructor.`
the role of the constructor is to initialize the variables/values.it is the "initialization function".The only reason i find on why we use a constructor instead of a normal function to initialize the variables is to stop different people from using different function names and avoid ambiguity and it is much more easier to use a constructor which is instantiated automatically as soon as the class is run,instead of having to write a separate code for instantiation.this may seem small and like something that doesn't require much work,but only for a very small program,for larger ones the struggle is real.
It is usual to put mandatory things into the constructor and optional ones into the Initialise function.
For example, consider an amplifier that requires a power source so that would be supplied to its constructor. Logically, you may want to turn it on and set its power level but one could argue that you might not want to do that until later. In pseudo-code:
class Amplifier
{
public Amplifier(PowerSource powerSource)
{
// create amplifier...
}
public int PowerLevel;
public void Initialise()
{
// turn on...
}
}
The example, above, is rather puerile but it illustrates the concepts at play. It is always an issue of design, however, and opinions do vary.
Some classes of object, however, will have to perform obvious set-up operations during their construction phase. In these cases, the requirement to have a constructor is very easy to understand. For example, if your object might require a variable amount of memory, the constructor would be a logical place to allocate it and the destructor or finaliser would be a logical place to free it up again.
Even if you don't use constructor it will call implicitly by your language translator whenever you create object.Why?
The reason is that it is used for object initialization means the variable(instance) which we declare inside our class get initialized to their default value.
class Person {
//Class have two parts
//1.Data(instance variable)
//2.Methods(Sub-routine)
String name;
int age;
}
public class Stack{
public static void main(String[] args){
Person person1 = new Person();
System.out.println("Name: "+person1.name);
System.out.println("Age: " + person1.age);
}
}
Output- Name: null
Age: 0
"null" and "0" are default values which are impicitly set by default constructor.
When we initialize a class by creating an instance or object the constructor is called automatically. This is very helpful when we need a huge amount of code to be executed every time we create an object.
The best use of constructor can be seen when we create a " graphical user interface". While building a GUI for an application we need to separate the code for designing the GUI and the business logic of the application. In such a case we can write the code for designing GUI, in a constructor and business logic in respective methods. This make the code tidy and neat too.
Also when an object is created the global variables can be initialized to their default values using constructor. If we don't initialize the global variables, then the compiler will do it implicitly by using the default constructor.
So constructor is a very wise concept which appears to be an idiosyncrasy at first but as you code further and more and more you will realize it's importance.
Because constructors are exactly for that: to avoid using an "initialize function"
Plus you can have have as many constructors as you want: you juste feed them some parameters, depending how you want to inialize your object.
Constructor is a special member function which has same name as class name and called whenever object of that class is created. They are used to initialize data field in object.
Constructor has following properties:
It has same name as class name.
It is called whenever object of a class is created.
It does not have return type not even void.
It can have parameters.
Constructor can be overloaded.
Default constructor is automatically created when compiler does not find any constructor in a class.
Parameterized constructor can call default constructor using this() method.
A constructor can be static for static data field initialization.
It is not implicitly inherited.
For More Info
https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
I am working on a little pinball-game project for a hobby and am looking for a pattern to encapsulate constant variables.
I have a model, within which there are values which will be constant over the life of that model e.g. maximum speed/maximum gravity etc. Throughout the GUI and other areas these values are required in order to correctly validate input. Currently they are included either as references to a public static final, or just plain hard-coded. I'd like to encapsulate these "constant variables" in an object which can be injected into the model, and retrieved by the view/controller.
To clarify, the value of the "constant variables" may not necessarily be defined at compile-time, they could come from reading in a file; user input etc. What is known at compile time is which ones are needed. A way which may be easier to explain it is that whatever this encapsulation is, the values it provides are immutable.
I'm looking for a way to achieve this which:
has compile time type-safety (i.e. not mapping a string to variable at runtime)
avoids anything static (including enums, which can't be extended)
I know I could define an interface which has the methods such as:
public int getMaximumSpeed();
public int getMaximumGravity();
... and inject an instance of that into the model, and make it accessible in some way. However, this results in a lot of boilerplate code, which is pretty tedious to write/test etc (I am doing this for funsies :-)).
I am looking for a better way to do this, preferably something which has the benefits of being part of a shared vocabulary, as with design patterns.
Is there a better way to do this?
P.S. I've thought some more about this, and the best trade-off I could find would be to have something like:
public class Variables {
enum Variable {
MaxSpeed(100),
MaxGravity(10)
Variable(Object variableValue) {
// assign value to field, provide getter etc.
}
}
public Object getVariable(Variable v) { // look up enum and get member }
} // end of MyVariables
I could then do something like:
Model m = new Model(new Variables());
Advantages: the lookup of a variable is protected by having to be a member of the enum in order to compile, variables can be added with little extra code
Disadvantages: enums cannot be extended, brittleness (a recompile is needed to add a variable), variable values would have to be cast from Object (to Integer in this example), which again isn't type safe, though generics may be an option for that... somehow
Are you looking for the Singleton or, a variant, the Monostate? If not, how does that pattern fail your needs?
Of course, here's the mandatory disclaimer that Anything Global Is Evil.
UPDATE: I did some looking, because I've been having similar debates/issues. I stumbled across a list of "alternatives" to classic global/scope solutions. Thought I'd share.
Thanks for all the time spent by you guys trying to decipher what is a pretty weird question.
I think, in terms of design patterns, the closest that comes to what I'm describing is the factory pattern, where I have a factory of pseudo-constants. Technically it's not creating an instance each call, but rather always providing the same instance (in the sense of a Guice provider). But I can create several factories, which each can provide different psuedo-constants, and inject each into a different model, so the model's UI can validate input a lot more flexibly.
If anyone's interested I've came to the conclusion that an interface providing a method for each psuedo-constant is the way to go:
public interface IVariableProvider {
public int maxGravity();
public int maxSpeed();
// and everything else...
}
public class VariableProvider {
private final int maxGravity, maxSpeed...;
public VariableProvider(int maxGravity, int maxSpeed) {
// assign final fields
}
}
Then I can do:
Model firstModel = new Model(new VariableProvider(2, 10));
Model secondModel = new Model(new VariableProvider(10, 100));
I think as long as the interface doesn't provide a prohibitively large number of variable getters, it wins over some parameterised lookup (which will either be vulnerable at run-time, or will prohibit extension/polymorphism).
P.S. I realise some have been questioning what my problem is with static final values. I made the statement (with tongue in cheek) to a colleague that anything static is an inherently not object-oriented. So in my hobby I used that as the basis for a thought exercise where I try to remove anything static from the project (next I'll be trying to remove all 'if' statements ;-D). If I was on a deadline and I was satisfied public static final values wouldn't hamstring testing, I would have used them pretty quickly.
If you're just using java/IOC, why not just dependency-inject the values?
e.g. Spring inject the values via a map, specify the object as a singleton -
<property name="values">
<map>
<entry> <key><value>a1</value></key><value>b1</value></entry>
<entry> <key><value>a2</value></key><value>b3</value></entry>
</map>
</property>
your class is a singleton that holds an immutable copy of the map set in spring -
private Map<String, String> m;
public String getValue(String s)
{
return m.containsKey(s)?m.get(s):null;
}
public void setValues(Map m)
{
this.m=Collections.unmodifiableMap(m):
}
From what I can tell, you probably don't need to implement a pattern here -- you just need access to a set of constants, and it seems to me that's handled pretty well through the use of a publicly accessible static interface to them. Unless I'm missing something. :)
If you simply want to "objectify" the constants though, for some reason, than the Singleton pattern would probably be called for, if any; I know you mentioned in a comment that you don't mind creating multiple instances of this wrapper object, but in response I'd ask, then why even introduce the sort of confusion that could arise from having multiple instances at all? What practical benefit are you looking for that'd be satisfied with having the data in object form?
Now, if the values aren't constants, then that's different -- in that case, you probably do want a Singleton or Monostate. But if they really are constants, just wrap a set of enums or static constants in a class and be done! Keep-it-simple is as good a "pattern" as any.