I want to know if it's possible to define a class with some sort of constructor or if I have to initialize every field by hand.
Constructors in wollok are defined using the 'constructor' keyword. For example:
class Point {
var x
var y
constructor(_x, _y) {
x = _x
y = _y
}
}
Related
what is the best way to hide an impl class behind an interface?
The companion creator works well, but needs to repeat all the arguments of the constructor twice.
Is there a way to simplify A.from(x,y,z,a,b,c,d) = AImpl(x,y,z,...)?
//the application will only see this interface
interface A {
val x: X
val y: Y
companion object {
//choose any implementation without breaking existing code
#JvmStatic
fun from(x: X, y: Y): A = AImpl(x = x, y = y) //inconvenient for many arguments
}
}
internal class AImpl(
override val x: X,
override val y: Y
) : A
fun someApplication() {
val a = A.from(..., ...) //no reference to AImpl
//use a: A
}
Thank you very much.
Martin
The way you wrote it is already good. If you're concerned about too many parameters, note that you don't have to name and pass every single one of them, and not every property needs to be passed as a constructor parameter. Depending on the implementation class, some properties can be defaulted or calculated:
interface A {
val x: X
val y: Y
companion object {
fun from(x: X, y: Y): A = AImpl(x)
}
}
internal class AImpl(
override val x: X,
) : A {
override val y = something()
}
Furthermore, AImpl doesn't have to be internal; it can be private or even an anonymous class, if it's a very short one (otherwise the code can become unreadable):
interface A {
val x: X
val y: Y
companion object {
fun from(x: X, y: Y): A = object : A {
override val x = x
override val y = y
}
}
}
Instead of using a member function of a companion object, a common Kotlin-idiomatic way is to use a standalone factory function with the same name as the interface:
fun A(x: X, y: Y): A = AImpl(x, y)
An example of such a function is MutableList: it has the same name as interface MutableList, and it happens to return an ArrayList but that's just implementation detail: it's only documented to return something that implements interface MutableList.
I don't really understand what are you tring to do.
So i'm not sure if this will be the answer to your question.
fun main() {
val x = X()
val y = Y()
val a = AImpl().from(x,y)
a.x.toString()
a.y.toString()
//use object class so you can use the class without ()
val b = BImpl.from(x,y)
b.x.toString()
b.y.toString()
}
class X{}
class Y{}
interface A
{
val x : X
val y : Y
fun from(xValue : X, yValue : Y) : A
}
internal class AImpl() : A {
override var x : X = X()
override var y : Y = Y()
override fun from(xValue : X, yValue : Y) : A {
x = xValue
y = yValue
return this
}
}
object BImpl : A {
override var x : X = X()
override var y : Y = Y()
override fun from(xValue : X, yValue : Y) : A {
x = xValue
y = yValue
return this
}
}
I don't think you should implementation anything in Interface
but If you want your code to work
companion object {
//choose any implementation without breaking existing code
#JvmStatic
//fun from(x: X, y: Y): A = AImpl(x = x, y = y)
//because you Return A That's why you got no reference to AImpl
//so don't return A but make it AImpl directly
//but it's still act like "A" interface.
fun from(x: X, y: Y) = AImpl(x,y)
}
}
open class Parent(){
protected var z : Int? = null
private fun getMyAge(){
val x = 65
val y = 10
z = x % y
}
}
class Child:Parent(){
ovveride fun getMyAge()
println(z) //here I get null
}
My question is: why I get null?
Am I getting a variable from an inherited class incorrectly?
It's because when you override the function, the super function is not called. If you want the function in parent class called, you must change your code to this:
open class Parent(){
protected var z : Int? = null
private fun getMyAge(){
val x = 65
val y = 10
z = x % y
}
}
class Child:Parent(){
ovveride fun getMyAge()
super.getMyAge()
println(z)
}
Given a class A and a group of instances B that are created in the same way but have no extra functionallity to the class.
What would be the better pattern
subclassing A overriding only the constructor
or have a function that creates instances of group B
e.g.
class A
{
int x;
int y;
}
option A:
class B
{
constructor()
{
super(0,random())
}
}
option B:
createB()
{
return new A(0,random())
}
EDIT:
class B constructor should've been using super
The better approach is definitely not to create additional functions.Constructors are meant for that and you should not move the logic away.
Rethink if you really need B class. Because if you don't, the whole code can be simplified to:
class A {
int x;
int y;
public A() {
x = 0;
y = Math.random();
}
public A(int x, int y) {
this.x = x;
this.y = y;
}
}
In most of the languages, constructors can be overloaded based on the number and types of parameters.
If you really need B class, I suggest simply calling super constructor:
class A {
int x;
int y;
public A(int x, int y) {
this.x = x;
this.y = y;
}
}
class B extends A {
public B() {
super(0, Math.random());
}
}
I am not sure what do you mean by "instances were created in the same way", but with OOP you can instantiate parent class with an instance of a child, e.g.:
A a = new A(10,20);
A b = new B();
It's better to use option B.
This is a classic pattern, named Fabric Method in fundamental book Gang of Four.
I'd like to hold a property of type X that extends Y, the getter should return Y and setter should be private and accept X.
Is this possible via a simple var definition, or do I need to use fun ?
Consider using additional backing property:
class Sample {
private var privateX: X
var publicY: Y
get() = privateX
}
I have a question regarding oop. It might seem really trivial. I have seen example online where they use this to access a private method. Is it really necessary? Is it language specific?
Here is an example which can be done with or withour this.
class A {
def test(): String = {
val x = this.test_2()
x
}
private def test_2(): String = {
"This is working"
}
}
object Main extends App {
val a = new A
val x = a.test
println(x)
}
Here the same code without this. both are working.
class A {
def test(): String = {
val x = test_2()
x
}
private def test_2(): String = {
"This is working"
}
}
object Main extends App {
val a = new A
val x = a.test
println(x)
}
Some languages won't accept the use of a method without the this, like python (self.), but in most case, it's a matter of readability and safety.
If you define a function out of the class with the same name as a method of the class, it can cause a problem.
By adding this, you know it's a method from the class.
The "this" keyword refers to the class which you are currently writing code in it. It is mainly use to distinct between method parameters and class fields.
For example, let's assume you have the following class:
public class Student
{
string name = ""; //Field "name" in class Student
//Constructor of the Student class, takes the name of the Student
//as argument
public Student(string name)
{
//Assign the value of the constructor argument "name" to the field "name"
this.name = name;
//If you'd miss out the "this" here (name = name;) you would just assign the
//constructor argument to itself and the field "name" of the
//Person class would keep its value "".
}
}