How do you do qualified superclass constructor invocation in Kotlin? - kotlin

I'm using Kotlin and Java together. I am looking for a way to extend a non-static nested class from Kotlin, but I have no idea how to do it.
From the JLS 1.8:
Example 8.8.7.1-1. Qualified Superclass Constructor Invocation
class Outer {
class Inner {}
}
class ChildOfInner extends Outer.Inner {
ChildOfInner() { (new Outer()).super(); }
}
I've tried to do like below but it doesn't really work in Kotlin:
class ChildOfInner(): Outer().Outer.Inner()

Using Kotlin we can inherit inner classes in this way:
class ChildClass : Outer() {
inner class ChildOfInner : Outer.Inner() {
}
}
So firstly we must inherit Outer class and then we are able to inherit Inner class.

Related

Kotlin inner/nested class instantiable only from parent

Is it possible to translate the following Java snippet into Kotlin? Maintaining guarantees offered by the access modifiers
public class Outer {
public Inner newInner() {
return new Inner();
}
public static class Inner {
private Inner() { }
}
}
Here is an idea I thought of. It could be considered slightly abusing abstract/sealed classes:
class Outer {
fun newInner(): Inner = PrivateInner()
sealed class Inner { // abstract class also works, but you allow subclassing from everywhere
init {
if (this !is PrivateInner) {
throw IllegalStateException("Do not subclass Outer.Inner!")
}
}
// implementations go here
}
private class PrivateInner: Inner()
}
A note on subclassing:
I used a runtime check to prevent people from subclassing Outer.Inner and instantiating the subclass. Unfortunately with this method, you cannot fully prevent subclassing, and preventing the instantiation of invalid subclasses can only be done at runtime.
A (weak) way to prevent subclassing is to use a sealed class. Making Outer.Inner sealed prevents subclassing from anywhere that is outside Outer's package.

Overriding Dart methods with Generics arguments

I have this case where I am extending from a super class with methods being typed using Generics as the following:
Models
abstract class SuperClass {
//.....
}
class SubClass extends SuperClass {
int a;
int b;
String c;
//....
}
Controllers
abstract class A {
T getDoc<T extends SuperClass>(T doc);
}
class B extends A {
T getDoc<T extends SubClass>(T doc) { //<================ Error
//....
}
}
Basically class B will only deal with a SubClass model and any class that extends it. Extending SuperClass is not enough. It's a way to enforce the type usage. I could add a helper function that will check the type for each method within class B (doc is SubClass) but seems like a lot repetition.
But the above architecture fails when overriding the method getDoc in class B saying that it isn't a valid override although SubClass is a SuperClass. How can I achieve something like this? Or is there a better way of doing it? Appreciate any pointers :)
I have finally a found a way :)
So I wanted the class B's methods to accept exclusively types that extend SubClass, but class A method's signature expects parameters extending class SuperClass.
To go about this I did the following:
Models
abstract class SuperClass {
//.....
}
class SubClass extends SuperClass {
int a;
int b;
String c;
//....
}
Controllers
abstract class A<K extends SuperClass> {
T getDoc<T extends K>(T doc);
}
class B extends A<SubClass> {
T getDoc<T extends SubClass>(T doc) {
//.......
}
}
can you use covariant modifier.
In your example:
abstract class A {
T getDoc<T extends SuperClass>(covariant T doc);
}
Check: https://github.com/dart-lang/sdk/blob/master/docs/language/informal/covariant-overrides.md
You can not narrow the generic type argument. Class B guaranties (by extending class A), that it will/can handle all type arguments (and sub types!), that class A can handle. Consider the following situation:
class OtherSubClass extends SuperClass {
//....
}
void main() {
var b = B();
b.getDoc(OtherSubClass());
}
What would you expect to happen? Class B is not able to handle objects of type OtherSubClass, so it breaks the contract with class A.

Why interface cant be used in kotlin inner class?

class SelectionRAdapter(var list: ArrayList<Image>) :
RecyclerView.Adapter<SelectionRAdapter.FolderRViewHolder>() {
inner class FolderRViewHolder(var view: View) :
RecyclerView.ViewHolder(view), View.OnClickListener {
init {
view.setOnClickListener(this)
}
override fun onClick(v: View?) {
view.checkbox_container.setBackgroundColor(Color.parseColor("59FFFFFF"))
}
interface OnItemSelectListener {
}
}
}
when I try add interface to kotlin inner class it shows interface not allowed here exception may i know the reason behind it? when i trying communicate with inner class with parent class using interface

What is the difference between 'open' and 'public' in Kotlin?

I am new to Kotlin and I am confused between open and public keywords. Could anyone please tell me the difference between those keywords?
The open keyword means “open for extension“ - i.e. it's possible to create subclasses of an open class:
The open annotation on a class is the opposite of Java's final: it allows others to inherit from this class. By default, all classes in Kotlin are final, which corresponds to Effective Java, Item 17: Design and document for inheritance or else prohibit it.
You also need to be explicit about methods you want to make overridable, also marked with open:
open class Base {
open fun v() {}
fun nv() {}
}
The public keyword acts as a visibility modifier that can be applied on classes, functions, member functions, etc. If a top-level class or function is public, it means it can be used from other files, including from other modules. Note that public is the default if nothing else is specified explicitly:
If you do not specify any visibility modifier, public is used by default, which means that your declarations will be visible everywhere
class A { ... } in Java is equal to open class A { ... } in Kotlin.
final class B { ... } in Java is equal to class B { ...} in Kotlin.
It is not related with public.
In Kotlin, everything without access modifiers is public by default. You can explicitly say public in the definition, but it is not necessary in Kotlin.
So,
public class A { ... }
and
class A { ... }
are the same in Kotlin.
I put here just for my memo, maybe useful for someone else :
open class in kotlin means that a class can be inherited because by default they are not:
class Car{....}
class Supercar:Car{....} : // give an error
open Car2{....}
class Supercar:Car2{....} : // ok
public class in Java is about the visibility of class (nothing to do with inheritance : unless a class in java is final, it can be inherited by default).
In kotlin all the class are public by default.
open method in kotlin means that the method can be overridden, because by default they are not.
Instead in Java all the methods can be overridden by default
The method of an open class cannot be overridden by default as usual (doesn't matter if the class is open), they must be declared that they can be overridden :
open class Car{
fun steering{...}
}
class Supercar:Car{
override fun steering {...} // give an error
}
open class Car2{
open fun steering{...}
}
class Supercar:Car2{
override fun steering {...} // ok
}
for more details : https://kotlinlang.org/docs/reference/classes.html
public: public keyword in Kotlin is similar to java it is use to make the visibility of classes, methods, variables to access from anywhere.
open: In Kotlin all classes, functions, and variables are by defaults final, and by inheritance property, we cannot inherit the property of final classes, final functions, and data members. So we use the open keyword before the class or function or variable to make inheritable that.
open is opposite to Final in java.
If the class is not 'open', it can't be inherited.
class First{}
class Second:First(){} // Not allowed. Since 'First' is Final(as in Java) by default. Unless marked "open" it can't be inherited
Don't get confused with open and public. public is a visibility modifier
class Third{} // By default this is public
private class Fourth{}
class Fifth{
val third = Third() // No issues
val fourth = Fourth() // Can't access because Fourth is private
}
All classes, methods, and members are public by default BUT not open
Keyword open in kotlin means "Open for Extension"
means if you want any class to be inherited by any subclass or method to be overriden in subclasses you have to mark as open otherwise you will get compile time error
NOTE: abstract classes or methods are open by default you do not need to add explicitly.
OPEN VS FINAL VS PUBLIC
OPEN :
child class can access this because they are inherited by its parent.
In Kotlin you need to add 'open' keyword unlike java whose all classes are 'open' by default
Example :
Kotlin : open class A () {}
Java : class A () {}
FINAL :
child class can't access or inherit.
In JAVA you need to add 'final' keyword unlike kotlin whose all classes are 'final' by default
Example :
Kotlin : class A () {}
Java : final class A () {}
PUBLIC : Any class whether its inherited or not can access its data or methods.
Example in Kotlin :
//Final
class DemoA() {
protected fun Method() {
}
}
class DemoB() : DemoA {
Method() // can't access
}
//OPEN
open class DemoA() {
protected fun Method() {
}
}
class DemoB() : DemoA {
Method() // can access
}
//Public
class DemoA() {
fun Method() {
}
}
class DemoB() {
val a = DemoA()
a.Method() // can access
}
Example in Java :
//FINAL
final class DemoA() {
protected void name() {
}
}
class DemoB() extends DemoA {
name(); // Can't access
}
//Open
class DemoA() {
protected void name() {
}
}
class DemoB() extends DemoA {
name(); // Can access
}
//Public
class DemoA() {
void name() {
}
}
class DemoB(){
DemoA a = new DemoA()
a.name(); // Can access
}
Summarized answer (Kotlin)
The defaults of declarations of classes, methods, and properties are
(public + final). final prevents any inheritance attempts.
In order to be able to extend a class, you must mark the
parent class with the open keyword.
In order to be able to override the methods or properties, you must
mark them in the parent class with the open keyword, in addition to
marking the overriding method or parameter with the override keyword.
public is just encapsulation, it affects the visibility of classes/ methods. Public will make them visible everywhere.
Reference

Base class and derived class

I have a question, I have a base class and an another class which derived from the base class. Can we access derived class in the base class.
Thanks in advance
You can access the code in the derived class from the base class code, but only from within an object which is actually a derived class object, and then only if the methods involved are virtual methods.
If you have an object which is itself an instance of the base class, then from within that instance you cannot see derived class code from the base class .
example
public class Baseclass
{
public void Foo()
{
Bar();
}
public virtual void Bar()
{
print("I'm a BaseClass");
}
}
public classs Derived: BaseClass
{
public override void Bar()
{
print("I'm a Derived Class");
}
}
Main()
{
var b = new BaseClass();
x.Foo() // prints "I'm a BaseClass"
// This Foo() calls Bar() in base class
var d = new Derived();
d.Foo() // prints "I'm a Derived Class"
// in above, the code for Foo() (in BaseClass)
// is accessing Bar() in derived class
}
No you can not. If you happen to know the an object declared as the Base class is actually the derived class, you can cast it. But within the base class you can not access the derived class's members.
There are a lot of ways that a base class can access members of a derived class (depending on programming language), but generally it is considered a design smell.
Instead, you usually want the base class to only directly access its own members, and allow derived classes to override methods.