Decoupling a definition of an interface from its implementation - oop

During the course of Tour of Go, the following extract is presented but I couldn't make much meaning of it (guess I'm lacking in OOP knowledge).
An interface in Go is defined as a set of method signatures. In Go interfaces are implicit. So there is no need to define on a given type that it implements a certain interface. The advantage of this is that the definition of an interface is decoupled from its implementation which could then appear in any package without prearrangement.
How is decoupling a definition of an interface from its implementation advantageous? My initial thought is that this approach greatly reduces the 'rigidity' (aka significance) of interfaces.. is it just syntactic-sugar and things actually "work as normal" under the hood?
Thank you for your time.

This is called "duck typing", and it allows interfaces to be defined where they are needed, instead of as part of the data type itself. Consider the following type:
type X struct {...}
func (X) f()
func (X) g()
func (X) h()
The type X has three methods, f(), g(), h(). If you have a data structure or function that needs to call a f() method, you can define an interface:
type FIntf interface {
f()
}
and now X implements that interface. You can pass instances of X wherever FIntf is needed.
If, in another module you need g() and h(), you can define an interface there:
type GIntf interface {
g()
h()
and now X implements GIntf.
This is especially useful if you have a third-party library that doesn't implement the interfaces you need. You can simply define an interface where you use it, and use the third-party types with the correct method set implement your interface.
The main advantage of this method is that you can still emulate the traditional notion of interfaces where you define an interface and a concrete implementation of it. On top of that, you have the flexibility to define different interfaces as you need them without modifying the implementation. In a language like Java, if you have a function that gets a certain interface and if your object doesn't, you have to write an adapter even though the method set exists on the original type. In Go, you don't need to do that.
Duck typing also allows for type-safety when it comes to calling methods. For instance, if you have a function that has to call method x() and y() of one of its arguments, define an interface containing x() and y(), and use a type assertion to validate the argument implements those two methods.

Related

Why do we need an explicit function interface modifier in Kotlin?

consider a SAM defined in Java
public interface Transform {
public String apply(String str);
}
This interface supports lambda to type conversion in Kotlin automatically
fun run(transform: Transform) {
println(transform.apply("world"))
}
run { x -> "Hello $x!!" } // runs fine without any issues
But now consider a Kotlin interface
interface Transform2 {
fun apply(str: String): String
}
Now the only way to invoke the run function would be by creating an anonymous instance of Transform2
run(object : Transform2 {
override fun transform(str: String): String = "hello $str!!"
})
but if we make the Transform2 interface a functional interface then the below is possible
run { str -> "hello $str!!" }
Why the Kotlin compiler cannot automatically type cast lambdas to matching interfaces (just as it does with Java interfaces) without needing to explicitly mark the said interfaces as a functional interface.
I've found some kind of a rationale in a comment in KT-7770:
... treating all the applicable interfaces as SAM might be too
unexpected/implicit: one having a SAM-applicable interface may not
assume that it will be used for SAM-conversions. Thus, adding another
method to the interface becomes more painful since it might require
changing syntax on the call sites (e.g. transforming callable
reference to object literal).
Because of it, current vision is adding some kind of modifier for
interfaces that when being applied:
Adds a check that the interface is a valid SAM
Allows SAM-conversions on call sites for it
Something like this:
fun interface MyRunnable {
fun run()
}
Basically, he is saying that if the SAM conversion were done implicitly by default, and I add some new methods to the interface, the SAM conversions would no longer be performed, and every place that used the conversion needs to be changed. The word "fun" is there to tell the compiler to check that the interface indeed has only one abstract method, and also to tell the call site that this is indeed a SAM interface, and they can expect the author to not suddenly add new abstract methods to the interface, suddenly breaking their code.
The thread goes on to discuss why can't the same argument can't be applied to Java, and the reason essentially boils down to "Java is not Kotlin".
This is speculation, but I strongly suspect one reason is to avoid encouraging the use of functional interfaces over Kotlin's more natural approach.
Functional interfaces are Java's solution to the problem of adding lambdas to the Java language in a way that involved the least change and risk, and the greatest compatibility with what had been best practice in the nearly 20 years that Java had existed without them: the use of anonymous classes implementing named interfaces. It needs umpteen different named interfaces such as Supplier, BiFunction, DoublePredicate… each with their own method and parameter names, each incompatible with all the others — and with all the other interfaces people have developed over the years. (For example, Java has a whole host of interfaces that are effectively one-parameter functions — Function, UnaryOperator, Consumer, Predicate, ActionListener, AWTEventListener… — but are all unrelated and incompatible.) And all this is to make up for the fact that Java doesn't have first-class functions.
Kotlin has first-class functions, which are a much more general, more elegant, and more powerful approach. (For example, you can write a lambda (or function, or function literal) taking a single parameter, and use it anywhere that you need a function taking a single parameter, without worrying about its exact interface. You don't have to choose between similar-looking interfaces, or write your own if there isn't one. And there are none of the hidden gotchas that occur when Java can't infer the correct interface type.) All the standard library uses function types, as does most other Kotlin code people write. And because they're so widely-used, they're widely supported: as part of the Kotlin ecosystem, everyone benefits.
So Kotlin supports functional interfaces mainly for compatibility with Java. Compared to first-class functions, they're basically a hack. A very ingenious and elegant hack, and arguably a necessary one given how important backward compatibility is to the Java platform — but a hack nonetheless. And so I suspect that JetBrains want to encourage people to use function types in preference to them where possible.
In Kotlin, you have to explicitly request features which improve Java compatibility but can lead to worse Kotlin code (such as #JvmStatic for static methods, or casting to java.lang.Object in order to call wait()/notify()). So it fits into the same pattern that you also have to explicitly request a functional interface (by using fun interface).
(See also my previous answer on the subject.)

Kotlin: Idiomatic usage of extension functions - putting extension functions next to the class it extends

I see some usages of Extension functions in Kotlin I don't personally think that makes sense, but it seems that there are some guidelines that "apparently" support it (a matter of interpretation).
Specifically: defining an extension function outside a class (but in the same file):
data class AddressDTO(val state: State,
val zipCode: String,
val city: String,
val streetAddress: String
)
fun AddressDTO.asXyzFormat() = "${streetAddress}\n${city}\n${state.name} $zipCode"
Where the asXyzFormat() is widely used, and cannot be defined as private/internal (but also for the cases it may be).
In my common sense, if you own the code (AddressDTO) and the usage is not local to some class / module (hence behing private/internal) - there is no reason to define an extension function - just define it as a member function of that class.
Edge case: if you want to avoid serialization of the function starting with get - annotate the class to get the desired behavior (e.g. #JsonIgnore on the function). This IMHO still doesn't justify an extension function.
The counter-response I got to this is that the approach of having an extension function of this fashion is supported by the Official Kotlin Coding Conventions. Specifically:
Use extension functions liberally. Every time you have a function that works primarily on an object, consider making it an extension function accepting that object as a receiver.
Source
And:
In particular, when defining extension functions for a class which are relevant for all clients of this class, put them in the same file where the class itself is defined. When defining extension functions that make sense only for a specific client, put them next to the code of that client. Do not create files just to hold "all extensions of Foo".
Source
I'll appreciate any commonly accepted source/reference explaining why it makes more sense to move the function to be a member of the class and/or pragmatic arguments support this separation.
That quote about using extension functions liberally, I'm pretty sure means use them liberally as opposed to top level non-extension functions (not as opposed to making it a member function). It's saying that if a top-level function conceptually works on a target object, prefer the extension function form.
I've searched before for the answer to why you might choose to make a function an extension function instead of a member function when working on a class you own the source code for, and have never found a canonical answer from JetBrains. Here are some reasons I think you might, but some are highly subject to opinion.
Sometimes you want a function that operates on a class with a specific generic type. Think of List<Int>.sum(), which is only available to a subset of Lists, but not a subtype of List.
Interfaces can be thought of as contracts. Functions that do something to an interface may make more sense conceptually since they are not part of the contract. I think this is the rationale for most of the standard library extension functions for Iterable and Sequence. A similar rationale might apply to a data class, if you think of a data class almost like a passive struct.
Extension functions afford the possibility of allowing users to pseudo-override them, but forcing them to do it in an independent way. Suppose your asXyzFormat() were an open member function. In some other module, you receive AddressDTO instances and want to get the XYZ format of them, exactly in the format you expect. But the AddressDTO you receive might have overridden asXyzFormat() and provide you something unexpected, so now you can't trust the function. If you use an extension function, than you allow users to replace asXyzFormat() in their own packages with something applicable to that space, but you can always trust the function asXyzFormat() in the source package.
Similarly for interfaces, a member function with default implementation invites users to override it. As the author of the interface, you may want a reliable function you can use on that interface with expected behavior. Although the end-user can hide your extension in their own module by overloading it, that will have no effect on your own uses of the function.
For what it's worth, I think it would be very rare to choose to make an extension function for a class (not an interface) when you own the source code for it. And I can't think of any examples of that in the standard library. Which leads me to believe that the Coding Conventions document is using the word "class" in a liberal sense that includes interfaces.
Here's a reverse argument…
One of the main reasons for adding extension functions to the language is being able to add functionality to classes from the standard library, and from third-party libraries and other dependencies where you don't control the code and can't add member functions (AKA methods).  I suspect it's mainly those cases that that section of the coding conventions is talking about.
In Java, the only option in this cases is utility methods: static methods, usually in a utility class gathering together lots of such methods, each taking the relevant object as its first parameter:
public static String[] splitOnChar(String str, char separator)
public static boolean isAllDigits(String str)
…and so on, interminably.
The main problem there is that such methods are hard to find (no help from the IDE unless you already know about all the various utility classes).  Also, calling them is long-winded (though it improved a bit once static imports were available).
Kotlin's extension methods are implemented exactly the same way down at the bytecode level, but their syntax is much simpler and exactly like member functions: they're written the same way (with this &c), calling them looks just like calling a member function, and your IDE will suggest them.
(Of course, they have drawbacks, too: no dynamic dispatch, no inheritance or overriding, scoping/import issues, name clashes, references to them are awkward, accessing them from Java or reflection is awkward, and so on.)
So: if the main purpose of extension functions is to substitute for member functions when member functions aren't possible, why would you use them when member functions are possible?!
(To be fair, there are a few reasons why you might want them.  For example, you can make the receiver nullable, which isn't possible with member functions.  But in most cases, they're greatly outweighed by the benefits of a proper member function.)
This means that the vast majority of extension functions are likely to be written for classes that you don't control the source code for, and so you don't have the option of putting them next to the class.

Is it possible to write default implementation of equals method in a Kotlin interface?

Is it possible to write default implementation of equals method in a Kotlin interface?
I have this code:
interface User {
val id: String
}
And I want all the classes implementing User to being compared using id property. Something like this:
interface User {
val id: String
fun equals(other: Any?) : Boolean {
//check type and stuff
return id == other.id
}
}
I know I can (and maybe should) use an abstract class, but I have to deal with this scenario now.
Thank you
No, I'm afraid that's not possible.
If you try your code, the compiler complains that:
        'equals' hides member of supertype 'Any' and needs 'override' modifier
And if you add the override modifier:
        An interface may not implement a method of 'Any'
The reasons are a bit obscure, and are inherited (!) from Java.
Originally, interfaces could only contain abstract methods (and constant fields).  When the ability to specify method implementations in interfaces was added, it was done in a way so as not to break existing code, so they only apply where classes don't already have an implementation.  (In Java they're called ‘default’ methods to reinforce that.)  If a class has an implementation, either defined within the class or in a superclass, that gets used, and the default is ignored.
There are a few corner cases, though: the methods defined in Object (Java's equivalent of Kotlin's Any).  Those are clone(), equals(), finalize(), getClass(), hashCode(), notify(), notifyAll(), toString(), and wait().  (Most of those are rarely used directly these days, but of course equals(), hashCode(), and toString() are very important.)
Because those methods are defined in Object, every class has a direct implementation of them (either from Object or some subclass).  And so the interface's default implementation can never be used.
Exactly the same applies to Kotlin/JVM and the corresponding methods defined in Any — in fact, the compiler makes it explicit by giving an error if you try to provide a default implementation of any of those methods, as shown above.
This is a shame, because there are cases where a default implementation of equals(), hashCode(), and/or toString() would be extremely useful!  But it would introduce complexity, fragility, and some surprising corner cases; see this answer for an authoritative explanation.

Is it true that for C++ to work similarly to OOP in Java, Ruby, Python, the function (or methods) must be declared virtual and what if not?

Is it true that for C++ to work similarly in terms of modern OOP as in Java, Ruby, Python, the function (or methods) must be declared virtual and if not, what "strange" behaviors may occur?
I think it is true that for Java, Ruby, Python, and possibly other OOP languages that are late comers such as PHP and Lua, and even Smalltalk and Objective-C, all methods are just what is known as "virtual functions"?
"Method" is an unfortunately overloaded term that can mean many things. There's a reason C++ prefers different terminology, and that's because not only does it do something different from other languages, but it intends to do something different from what other languages do.
In C++ you call a member function. i.e. you externally make a call to a function associated with an object. Whether that function is virtual or not is secondary; what matters is the intended ordering of your actions - you're reaching into the object's scope, and commanding it to take a specific action. It might be that the object can specialize the action, but if so, it warned you in advance that it would do this.
In Smalltalk and the languages that imitate it (Objective-C most closely), you send a message to an object. A message is constructed on your side of the call consisting of a task name (i.e. method selector), arguments, etc., and the packed up and sent to the object, for the object to deal with as it sees fit. Semantically, it's entirely the object's decision what to do upon receipt of the message - it can examine the task name and decide which implementation to apply dynamically, according to a user-implemented choice process, or even do nothing at all. The outside calling code doesn't get to say what the object will do, and certainly doesn't get any say in which procedure actually runs.
Some languages fall in the middle ground, e.g. Java is inspired by the latter, but doesn't give the user any way to specify unusual dynamic responses - for the sake of simplicity every message does result in a call, but which call is still hidden from the external code, because it's entirely the object's business. C++ was never built on this philosophy of messages in the first place, so it has a different default assumption about how its member functions should operate.
The thing is that C++ is like the great grand father. It has many features, which often requires huge code definition.
Consider an example:
class A
{
virtual void fn() = 0;
};
class B: A
{
void fn();
};
#include "a.hpp"
#include "b.hpp"
int main()
{
A *a = new B();
a->fn();
}
This would implement overriding in C++.
Note that virtual void fn()=0 makes the class A abstract, and a pointer to base class (A) is essential.
In Java, the process is even simpler
abstract class A
{
abstract void fn();
}
class B extends A
{
void fn() {
//Some insane function :)
}
}
public static void main(String[] args) {
B ob = new B();
ob.fn();
}
Well, the effect is same; but the process is largely different. In short, C++ does have many features implemented in languages like Java, Ruby etc. but it is simply implemented using some (often complicated) techniques.
Regarding Php, since it is directly based on C++, there exists some syntax similarities between C++ and Php.
It is true that (for example) in Java all methods are virtual by default. In C++ it is possible to overload a non-virtual function (as opposed to overriding a virtual function) in a subclass, leading to possible counter-intutive behaviour, when only the base function is actually executed via a pointer or reference to the base class (i.e. when polymorphic behavior would normally be expected).
Because C++ is a value-based (as opposed to reference-based) language, then even when a function has been declared as virtual, the well known
object slicing problem can still arise: the superclass method is invoked when the type of a value object of a subclass is `cut down' to that of the base class (e.g. when the subclass is passed to a function which takes a base class argument by value).
For this reason, it is recommended to make all non-leaf classes abstract, something which is often achieved by providing a virtual destructor, even if such would otherwise be gratuitous.

AWT Component and custom interface types: how to write good OOP code?

Let's say I have a Swing GUI that has to display a certain type of information in two different ways. From a design patterns perspective one would probably use the Strategy pattern here: create an interface that defines how the communication between the display component and the client works like this:
public interface Foo {
void showData(Data bar)
}
The real action is then done by different components that implement Foo and can be created and plugged in for doing the real work.
Now, what happens, if the real components are java.awt.Components? As I see it, it results in a mess of type casts because Component is a class. Let's assume an implementation like this one:
public class Baz extends Component implements Foo {
...
}
If I want to pass objects of class Baz around, the methods can either use "Component" as the parameter type or "Foo". The problem is that some methods need objects that are both Component and Foo (e.g. because they add the object to a JPanel and then supply the data calling the interface method showData()).
As I see it I have some choices to make this happen:
I can pass the reference as Component and cast to Foo. Before, I have to check that the reference is an instance of Foo and I have to handle situations where this requirement is not met. Another problem is that I have to communicate to clients of the method that the Component passed also has to implement Foo, which is awkward and error-prone.
I can do the same thing with Foo
I can add a method "Component getComponent()" to the Foo interface and the implementation would always return "this". This boilerplate method could be put into an abstract sub-class of Component. This solution means an interface method I don't want and an additional sub-class I don't need.
I can pass two references, one Component and one Foo reference to the same object. Internally, I'd have to make sure, though, that both references belong to the same object. And I have to deal with situations in which this requirement is not met.
I can use an abstract sub-class of Component and define the interface using abstract methods. This would allow me to pass references in a type-safe manner, but break with good OOP practices: keeping interfaces and implementations separate and also the interface segregation principle.
So, all of these solutions are merely workarounds. Is there any solution I'm missing? What should I do?
I would use the Strategy design pattern as you mentioned, but perhaps in a different context. The problem with trying to "shoe-horn" both Foo and Component into one class is that you could have combinations of implementations that would require duplicating code.
For example, imagine you have the following implementations of Component:
(Its been too long since Ive used Swing, these classes may not exist)
JPanel
JButton
JMenu
And you also had the following implementations of Foo
MyFoo
HisFoo
OurFoo
WhatTheFoo
And Imagine all the combinations of those: that's whats called a class explosion. This is the classic justification for the Strategy pattern.
I would create a sort of container class that uses a HAS-A relationship for each of the needed classes instead of using the IS-A relationship as follows:
(Im a c++ programmer, so you'll have to excuse the hybrid code :)
class ComponentFooHandler {
Component component_;
Foo fooImpl_;
inline Foo getFoo() {return fooImpl_;}
void setFoo(Foo f) {fooImpl_ = f;}
Component getComponent() {return component_;}
void setComponent(Component c) {component_ = c;}
void doAction() {
component_.someAction();
fooImpl_.anotherAction();
}
}
You would then have to create different implementations of Foo seperately. Then the Component and Foo implementations can be combined as needed with out having to duplicate Foo impl code. Notice also that you can call methods that like doAction() that can operate on both Foo and Component without knowing their details, similar to a Template Pattern.
To solve the issues with your original question:
When a Component is needed, call getComponent() on a handler instance
When a Foo is needed, call getFoo() on a handler instance
I would avoid creating methods that need both in one and split the method args into 2
Or just consider passing around a ComponentFooHandler