Showing posts with label inheritance. Show all posts
Showing posts with label inheritance. Show all posts

Friday, 23 July 2021

Kotlin : the "by" keyword in Interface/Class Delegation

I'm writing it down here, because I looked at it and didn't understand what was going on.

The "by" keyword in Kotlin is used for two things:

  1. Interface/Class delegation1
  2. Delegated properties2

Delegation is a good alternative to inheritance (thought this last statement really requires explanation, or a blogpost on it's own,... or, dare I say, a study on when to use inheritance and when to use delegation and when to use the good old composition).

With the "by" keyword it is possible to use delegation, without adding to the amount of boilerplate that this entails and without having to use inheritance.

Let us give an example using Stubs in testing.

Stubs

So, it seems it's possible to create a simple stub for a test, by using an interface and an implementation and overriding a method (for stubbing). Naturally, the method is not "overridden", but using delegation it is simply implemented in the test, and all other methods are redirected to the stub (which is the delegation class).

So, the syntax1 looks like this:

val/var <propertyname>: <Type> by <expression>

So, for example if you wish to use a delegation (instead of inheritance) in your stub for an OrderService interface.

You create a OrderServiceStub, which makes an empty implementation of all the methods in de OrderService.

And then you can create an anonymous class, indicating which method you wish to change to benefit the test.

It looks like this:

Notice that the anonymous inner class does not inherit from OrderServiceStub (in Kotlin classes are final by default, and we'd like to keep it that way).

The way this can be done without boilerplace in Kotlin is as follows:

So in the second test we're creating an anonymous class, which implements the interface automatically by delegating to the Stub. The only thing we need to change is the method we're interested in.

The next blogpost, we will be diving deeper into Delegated Properties, which looks a little more complicated but is based on the same ideas.

References

[1] Kotlin Language Reference - Delegation
https://kotlinlang.org/docs/delegation.html
[2] Kotlin Language Reference - Delegated properties
https://kotlinlang.org/docs/delegated-properties.html
[3] StackOverflow - What does 'by' keyword do in Kotlin?
https://stackoverflow.com/questions/38250022/what-does-by-keyword-do-in-kotlin

Thursday, 20 May 2021

Java Inheritance for Beginners

Just a little exercise, to get things in perspective.

Besides, I thought I was being clever, but made a rookie mistake and it just didn't work1.

Something similar can be found in Java Puzzlers2.

During compile time a decision is made which method is to be called (§15.12)3. During compile time it is as yet unknown which type/subtype it will be. The compiler tries to be as specific as possible, but in this case, it will just be Animal in the second testcase.

References

[1] Stackoverflow - Overloaded method selection based on the parameter's real type
https://stackoverflow.com/questions/1572322/overloaded-method-selection-based-on-the-parameters-real-type
[2] Java Puzzlers - Traps, Pitfalls, and Corner Cases - By Joshua Bloch and Neal Gafter
http://www.javapuzzlers.com/
[3] JLS 16 - 15.12. Method Invocation Expressions
https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.12

Thursday, 10 May 2018

Default method 'toString' overrides a member of 'java.lang.Object'

An interface "inherits" methods from the Object class. I wrote about this here1.

The quotes are appropriate, because Interfaces can only inherit from other Interfaces. An interface, when it does not have a super interface, declares all public non-final methods of the Object as members of the Interface (if not explicitly defined in the interface.

I recently attempted something like this TaxBracket2:

It doesn't work. In fact my IDE started complaining immediately with the following message.

Default method 'toString' overrides a member of 'java.lang.Object'

It is supposed to do that, so says the Java Language Spec3:

It is a compile-time error if a default method is override-equivalent with a non-private method of the class Object, because any class implementing the interface will inherit its own implementation of the method.

My colleague helpfully provided the alternative, which is to make an "elementString()" method in the Interface, which can be called in the toString() method of every Class that implements the Interface. (Further down in the JLS, this approach is almost word for word also given)

StackOverflow4 has a helpful link to the JDK mailinglist5 that explains it a lot more in depth.

One of the remarks that really struck a cord with me, is the fact that toString(), equals() and hashCode() are all basically related to the state of a Class, and do not belong in an Interface.

I have therefore decided to remove the offending default method.

References

[1] Do interfaces inherit from object class?
http://randomthoughtsonjavaprogramming.blogspot.nl/2017/07/do-interfaces-inherit-from-object-class.html
[2] Wikipedia - Tax bracket
https://en.wikipedia.org/wiki/Tax_bracket
[3] JLS 8 - 9.4.1.2. Requirements in Overriding
https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4.3
[4] StackOverflow - Java8: Why is it forbidden to define a default method for a method from java.lang.Object?
https://stackoverflow.com/questions/24016962/java8-why-is-it-forbidden-to-define-a-default-method-for-a-method-from-java-lan
[5] Malinglist OpenJDK - Allow default methods to override Object's methods
http://mail.openjdk.java.net/pipermail/lambda-dev/2013-March/008435.html

Thursday, 27 July 2017

Do interfaces inherit from Object class in java?

I was thinking this question suddenly at work...

Quick, Batman! To the StackOverflow1!!!

The answer comes straight from the JSL2.

References

[1] StackOverflow - Do interfaces inherit from Object class in java
https://stackoverflow.com/questions/6056124/do-interfaces-inherit-from-object-class-in-java
[2] JLS Java 8 - 9.2. Interface Members
http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.2

Thursday, 29 June 2017

UML - What do those Arrows Mean?

In PlantUML:
@startuml
abstract class Animal
interface Behaviour
interface Prey
Animal <|-- Lion : inheritance
Behaviour <|.. Animal : realization/implementation
Lion -left-* Pride : composition
interface Grouping
Grouping <|.. Pride
Prey -left-O Lion : aggregation
Water <-down- Lion : uni-directional
Habitat -up- Lion : bi-directional
@enduml
implementation/realization
a dotted line with a closed, unfilled arrow means realization (or implementation). The arrow points to the interface.
inheritance
Inheritance is indicated by a solid line with a closed, unfilled arrowhead pointing at the super class
aggregation
a solid line with an unfilled diamond at the class which uses the other class
composition
a solid line with an filled diamond at the class which contains the other class
bi-directional association
A bi-directional association is indicated by a solid line between the two classes. In the example, the Lion lives in his Habitat, but the Habitat benefits in some way from the Lion as well.
uni-directional association
A uni-directional association is indicated by a solid line between the two classes. The class that knows nothing of the other class, has an open arrowhead pointing to it. A Lion uses Water, but not the other way around.

References

[1] Wikipedia - Class diagram
http://en.wikipedia.org/wiki/Class_diagram
[2] IBM Developer Works - UML basics The class diagram
https://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/bell/
What's the difference between Aggregation and Composition?
http://randomthoughtsonjavaprogramming.blogspot.nl/2013/11/whats-difference-between-aggregation.html

Thursday, 21 April 2016

Constructors, Javadoc and Inheritance

I recently had the problem that I defined some very good javadoc documentation on a constructor in one of my generic classes that is inherited a lot.

The documentation, however, is never propagated to subclasses, because constructors are not inherited1.

It is too bad that I already have to duplicate Constructors in my subclasses, but now I have to duplicate the documentation as well?

Right now, the best solution I can think of is to add a "@see" link to the appropriate super constructor. Like so:

There is a feature request/bug2 defined to expand the {inheritedDoc} to also work on constructors. But it has not seen any love for a long time.

References

[1] StackOverflow - Why is inheritedDoc not defined on constructors?
http://stackoverflow.com/questions/14848999/why-is-inheriteddoc-not-defined-on-constructors
[2] JDK-4810216 : Allow {@inheritDoc name} for constructors
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4810216

Sunday, 26 October 2014

Covariant return type

“In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass.”

Since JDK 5.0 it is possible to provide covariant return types in methods of subclasses.[2] Before this release, the Java programming language was invariant with regard to method return types.

Unfortunately, covariance is not possible with method parameters. If you wish to use that, reference [1] has a good explanation of how to do this using Generics.

Example

Scala

In Scala all three are possible, contravariant, covariant and invariant for both method parameters as well as method return types. It is used fairly frequently.

For more information, the blog in [3] has some excellent explanation.

References

[1] Covariant Parameter Types
https://www.java-tips.org/java-se-tips-100019/24-java-lang/482-covariant-parameter-types.html
[2] Wikipedia - Covariant return type
http://en.wikipedia.org/wiki/Covariant_return_type
[3] Atlassian Blogs - Covariance and Contravariance in Scala
http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/