How do we create custom getters and setters, and what’s the advantage of doing so in Flutter? - flutter

What is the reason of using custom getters and setters in an application.

That's fairly very simple
First let me show you a sample of how getters and setters in Dart look like, which is essentially the language behind Flutter
class Foo {
// Creating a field/instance variable
String _fooName; //Keeping it private always
// Using the getter
String get foo_name {
//We can do something else here, like saving the variable somewhere and then returning it to the caller function
return _fooName;// private variable return for use in outside class
}
// Using the setter method
set foo_name (String name) {
// We can do something else, like update another variable based on fooName
this._fooName = name;//private variable being assigned new value
}
}
From the name, setters are involved in setting the values to an instance variable in an object oriented programming paradigm whereas getters are involved in getting the value of an instance variable
Now you would ask why not return the instance variable directly and why having such a roundabout approach to setting and getting the value
Well the answer is while getting as well as setting, we might want to do some other operation too other than just setting or getting the value and it's always better not to give admin access to the variables and that's why they are private so as to promote consistency within the objects accessing the field

It's a matter of preference, but you really shouldn't needlessly create one for a single field
https://dart.dev/guides/language/effective-dart/usage#dont-wrap-a-field-in-a-getter-and-setter-unnecessarily
One use case for creating a setter would be to perform some type of validation
For a getter, it'd be useful for a calculated field based on other properties, rather than a single property alone

Related

How to create multiple setters

I have a variable which I want to give the option to call the setter with multiple types, but I would set the variable with one type of course. For example, if I have a variable called list, I want to be able to call the setter using a single list item i.e. a string and then in the setter method I would add the string to the end of the list. Another way to set the variable would be through an actual list, and the setter, I would just set the list to the list passed in.
Here's an example of what I would like to do, but the second time I call the list setter method, I get an error saying The name 'list' is already defined:
List<String> _list = [];
List<String> get list => list;
set list(List<String> newList) {
_list = newList;
}
set list(String newListItem) {
_list = [..._list, newListItem];
}
As Remi mentioned, it is not possible to do so. I would argue that it would be best not to do so because it changes the expectation of the contract of the setter. That is, you expect a setter to replace the value of a variable. Having a setter that appends to it is counter-intuitive and will lead to confusion for other developers.
Generally, for the maintainability of a code base, it's better to have an explicit interface to your class's behavior than to provide terse shortcuts.
That is not possible.
In Dart you can have only one setter per variable.
You will need to rename one of your setters to use a different name.

Property inheriting class

Forgive me if the title is confusing or it's stupid but am little confused on this
var logInUser : User!
This is the code logInUser is a property and User is model class now what's confusing to me is that is it a property inheriting a model class or is it something else and why we are force unwrapping it?
Now through this LogInUser we can access all properties of User model class
What the line you have posted above says is that your type has a property called logInUser. The property is of type User. Therefore if you access that property, you will have an object of type User and can work with it as such. If for example your User type has a property called firstName you could access that property by saying var userFirstName = logInUser.firstName for example.
The explanation point (!) means that your logInUser variable is an implicitly unwrapped optional. This means that you are saying to the compiler "this variable, although an optional, should ALWAYS be force unwrapped when accessed". Even though the property is an optional, you will not need to use if/let binding or force unwrapping to access it. If you do access the property and it is nil, you will get a runtime crash.
1) There is no inheritance in this statement, what's happening is simple:
A model is a representation of real/imaginary things in a bit world, in simple ways.
This means that the model "User" represent the user of the application and contains all the things needed to do this representation.
For example, what an user needs to be uniquely recognized by the system Email/username or both, for example. Obviously, a model can contain anything useful, for example to make an order the model should contain even the address.
Now, what's important is that a model is just a model and this means that you can use that model to literally create users in your system/app.
To write something like
var loginUser: User
Maybe, in the case of an iOS app, in a view controller, means that the controller needs to know who is the user who is using the app.
So, the loginUser is a variable representing an instance of User model, which means that loginUser is-a User, not its inheritance.
More technically, in your case if your User class (model) contains for example the property email, you can access that email by typing logInUser.email and do something like showing it or using it to authentication and so on.
Notice that I have used the work class which is actually a model, while logInUser is an object, which is an instance of a class, that is a concretization of the class. That means that you can have multiple object of the same class representing different users, for example: var adminUser: User, var customerUser: User, var loggedInUser: User which are different users with different informations and so they are different instances of the same class.
check this object programming explanation
2) The exclamation point is a forced unwrap, that means that a user can or cannot exists and it is not needed its initialization in an init because it could be nil (but you have to give it a valid value to use it), that stands for "non-existing". Actually, the notation var someV: User? says that your variable can contain an User type or a nil value.
The difference of your notation with ! from
var logInUser: User?
is that when you're using the variable, if you declared it with !, you can use it without unwrap it:
func someFunction(){
var email = logInUser.email
}
But this could fail if you didn't initialized your logInUser somewhere.
If you used ? instead, you need to unwrap it:
func someFunction(){
var email = logInUser?.email
// OR
var email2 = logInUser!.email
}
The difference in the previous use of logInUser is that logInUser?.email can return nil, while logInUser!.email try to force the unwrap and if it fails your app will crash.

Cannot Set Getters and Setters in Swift

I have created a custom class and I want to add associated getters and setters. I have read the official documentation from Apple and notice that when setting a getter and setter, you actually create a separate variable, which seems really confusing. For instance, in the documentation linked above, getters and setters are applied to a new variable called perimeter to obtain values from another variable called sidelength. Below is my code:
Getters and setters like you are implementing them are only used for computed variables in Swift. A variable with a getter and setter doesn't actually store anything, but does something when assigned or used for its value with other variables. When appropriate to use, the usage would be more like this.
var _key: String?
var key: String? {
get {
return _key
}
set {
_key = newValue
}
}
You would rarely if ever use this on an identical data type though. I use these for communication with CoreData often, and setting things like dates as a string or back to a date. Occasionally I might use it to handle the change in an optional to a non optional.
Getters and setters are not needed in order to use the variable in Swift though. If you are used to languages with them, I can understand the confusion here, but forget the correlation and start over with how you think about it. I am sure after a short amount of time, you will like the way Swift works with its datatypes!
Edit:
In order to do what you want, all you need is this:
class PollCell: UICollectionViewCell {
var key: String?
}
Now you can assign any value you want to cell.key and retrieve any value you want from cell.key.

Different ways of making read public write private variables in swift?

I've completed a online course that taught us to write properties of classes as:
class bar {
private var _foo:Int
var foo {
return _foo
}
}
Since then i've seen
class bar {
private (set) var foo:Int
}
Is there any difference between these two ways of writing things, and which would be best practise?
The second option is simpler and clearer and it has the added benefit of still being able to add get, set, willSet, and didSet blocks on the property while still having clearly defined scope on the getter and setter. Of course you can still add those to the private property but I think the code starts to get less readable.
Also note that the first option is a public read-only computed property making use of a private stored property.
The second option can be either a computed or stored property.

What is exactly the point of auto-generating getters/setters for object fields in Scala?

As we know, Scala generates getters and setters automatically for any public field and make the actual field variable private. Why is it better than just making the field public ?
For one this allows swapping a public var/val with a (couple of) def(s) and still maintain binary compatibility. Secondly it allows overriding a var/val in derived classes.
First, keeping the field public allows a client to read and write the field. Since it's beneficial to have immutable objects, I'd recommend to make the field read only (which you can achieve in Scala by declaring it as "val" rather than "var").
Now back to your actual question. Scala allows you to define your own setters and getters if you need more than the trivial versions. This is useful to maintain invariants. For setters you might want to check the value the field is set to. If you keep the field itself public, you have no chance to do so.
This is also useful for fields declared as "val". Assume you have a field of type Array[X] to represent the internal state of your class. A client could now get a reference to this array and modify it--again you have no chance to ensure the invariant is maintained. But since you can define your own getter you can return a copy of the actual array.
The same argument applies when you make a field of a reference type "final public" in Java--clients can't reset the reference but still modify the object the reference points to.
On a related note: accessing a field via getters in Scala looks like accessing the field directly. The nice thing about this is that it allows to make accessing a field and calling a method without parameters on the object look like the same thing. So if you decide you don't want to store a value in a field anymore but calculate it on the fly, the client does not have to care because it looks like the same thing to him--this is known as the Uniform Access Principle
In short: the Uniform Access Principle.
You can use a val to implement an abstract method from a superclass. Imagine the following definition from some imaginary graphics package:
abstract class circle {
def bounds: Rectangle
def centre: Point
def radius: Double
}
There are two possible subclasses, one where the circle is defined in terms of a bounding box, and one where it's defined in terms of the centre and radius. Thanks to the UAP, details of the implementation can be completely abstracted away, and easily changed.
There's also a third possibility: lazy vals. These would be very useful to avoid recalculating the bounds of our circle again and again, but it's hard to imagine how lazy vals could be implemented without the uniform access principle.