Use static method from Java class which is extended in kotlin class - kotlin

I have a Parent class written in Java file
public class ParentClass {
public static int method1() {
return 1;
}
}
I have a Child class written in kotlin
class ChildClass: ParentClass() {
companion object {
#JvmStatic
fun childMethod1(): Int {
return 100
}
}
}
Similarly, I have a child class written in Java
class JavaChildClass extends ParentClass {
public static int childMethod1() {
return 200;
}
}
Now, in my main kotlin class, I am trying to access the methods,
val result1 = JavaChildClass.childMethod1() //Method in the Java child class
val result2 = JavaChildClass.method1() //Method in the parent class
val result3 = ChildClass.childMethod1() //Method in Kotlin Child class
val result4 = ChildClass.method1() //Error, cannot access this method

Related

What's the meaning of interface as dependency of a class in Kotlin?

interface SomeInterface {
fun someFunction()
}
class SomeClass(private val someInterface: SomeInterface) {
}
What does it mean? As far as I know, interface can't instantiate objects and if it can then where should I implement someFunction()?
You are correct that you cannot instantiate SomeInterface directly, but you can pass implementations of your interface to SomeClass. This way SomeClass can use someFunction() but doesn't care about the lower-level implementation details of the interface (aka polymorphism).
interface SomeInterface {
fun someFunction()
}
class SomeClass(private val someInterface: SomeInterface) {
fun doSomething() = someInterface.someFunction()
}
class SomeImplementation(): SomeInterface {
override fun someFunction() {
println("did something")
}
}
fun main() {
val someClass = SomeClass(SomeImplementation())
someClass.doSomething()
}

Why does companion object put const vals into parent class?

I have a class in Kotlin:
class AClass {
companion object {
const val CONST_VAL = "THIS IS A CONST VAL STRING"
val JUST_VAL = "THIS IS A NON-CONST VAL STRING"
fun aFunction() {}
}
}
and a Main class in Java which is accessing companion members:
public class Main {
public static void main(String[] args) {
// aFunction can only be accessed by using Companion
AClass.Companion.aFunction();
// CONST_VAL can only be accessed from the parent class
String constValString = AClass.CONST_VAL;
// JUST_VAL can only be accessed with Companion
String valString = AClass.Companion.getJUST_VAL();
}
}
How come, in Java, both #aFunction() and JUST_VAL can only be accessed via the Companion while CONST_VAL can only be accessed via the parent class directly? Shouldn't CONST_VAL be accessed only via the Companion as well?

Mockito mock with constructor parameter

I am using mockito 1.9.5 and wanting to test a class that i have posted on github.
The issue is that I need to mock the getStringFromExternalSources method.
MyClass code:
public class MyClass {
String a,b,c;
public MyClass(String a, String b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
public String executeLogic (String d) {
return a + b + c + d;
}
public String getStringFromExternalSources (){
return "i got it from some place else";
}
}
My current test:
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Test
public void MyClassTest() {
MyClass mc = Mockito.spy(new MyClass("a","b","c") );
Mockito.doReturn("mock").when(mc.executeLogic("real"));
Mockito.doReturn("externalString").when(mc.getStringFromExternalSources());
System.out.println(mc.executeLogic("real"));
}
}
Any pointers ?
You can mock any method using when().thenReturn() construct.
Example:
MyClass mc = Mockito.spy(new MyClass("a","b","c"));
when(mc.getStringFromExternalSource()).thenReturn("I got it from there!!");
So whenever the method 'getStringFromExternalSource()' is invoked for the mocked object mc then it will return "I got it from there!!".
if you want to Test class with different parameters then you can use #Parameters annotation to provide parameters to the class in conjunction with Parameterized runner and mention the parameters in a public static method with #Paramters annotation. A rough example would be:
#RunWith(Parameterized.class)
class SomeTestClass{
#Mock
SomeTestClass mSomeTestClassInstance;
#Parameters
public static Object provideParameters() {
Object[] objects = new Object[]{
0,
0,
2
};
return objects;
}
public SomeTestClass(Object argument1){
mArgument1 = argument1;
}
#Test
public void testSomeMethod{
Object returnValue = mSomeTestClassInstance.testSomeMethod(mArgument1);
assertequals(mArgument1,returnValue)
}
}
How to mock getStringFromExternalSources method:
public class MyClassTest {
#Test
public void MyClassTest() {
MyClass mc = mock(MyClass.class);
when(mc.executeLogic("real").thenReturn("mock");
when(mc.getStringFromExternalSources().thenReturn("externalString");
System.out.println(mc.executeLogic("real"));
}
}

Overriding Concept in Abstract Classes with code example in c#

I am trying to access the object of my RepositoryJournalVoucher.cs class from my main class named RepositoryVoucher.cs but i am unable to access or make instance, dont know why.
abstract class RepositoryUniversalAccounts.cs
namespace eCartDynamic.RepositoryApplication
{
public abstract class RepositoryUniversalAccounts
{
public string AccountCode { get; set; }
public abstract string PostVoucher();
}
}
RepositoryCashVoucher.cs
namespace eCartDynamic.RepositoryApplication
{
public class RepositoryCashVoucher : RepositoryUniversalAccounts
{
public override string PostVoucher()
{
AccountCode = "16-01-001-01-000001-CV";
return "CV Posted Sucessfully";
}
}
}
RepositoryJournalVoucher.cs
namespace eCartDynamic.RepositoryApplication
{
public class RepositoryJournalVoucher : RepositoryUniversalAccounts
{
public override string PostVoucher()
{
AccountCode = "16-01-001-01-000001-JV";
return "JV Posted Sucessfully";
}
}
}
Main Class. RepositoryVoucher.cs
namespace eCartDynamic.RepositoryApplication
{
public class RepositoryVoucher
{
RepositoryUniversalAccounts abc = new RepositoryJournalVoucher();
}
}
in my RepositoryVoucher.cs Class i am not be able to make object of anything like:
RepositoryUniversalAccounts abc = new RepositoryJournalVoucher();
RepositoryJournalVoucherabc obj = new RepositoryJournalVoucher();

Extends common class and implement interface

(This example written by Typescript but not only in Typescript case)
class IMyInterface {
doC:(any) => any;
}
class Common {
commonProperty:any;
doA() {
}
doB() {
}
}
class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class Factory {
myClass: Common;
doSomething() {
// Property 'doC' does not exist on type 'Common'
this.myClass.doC('test');
}
}
Class A and B are extended Common class, so that in Factory class can define myClass type as Common.
But Class B need to implement IMyInterface, which Common class doesn't contained. So the Factory class throws an error that the interface method is not existed on Common class.
How and what's the best way to solve this?
[Edited]
First of all, #basarat thank you very much, but I'm still curious a little,
What if there are some more classes which implements IMyInterface
class ClassC extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class ClassD extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class ClassE extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
In that case, I can think, I can define the doC() method in Common class.
But also I want to make ClassB, C, D and E must implement the Doc method.
please advise me,
How and what's the best way to solve this
You basically want to say that myClass is generally just Common but in a special case it might be ClassB. You can do this using a union type + using a typeguard:
class Factory {
myClass: Common | ClassB;
doSomething() {
const myClass = this.myClass;
if (myClass instanceof ClassB){
// works!
myClass.doC('test');
}
}
}
More
Complete example:
class IMyInterface {
doC:(any) => any;
}
class Common {
commonProperty:any;
doA() {
}
doB() {
}
}
class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class Factory {
myClass: Common | ClassB;
doSomething() {
const myClass = this.myClass;
if (myClass instanceof ClassB){
// works!
myClass.doC('test');
}
}
}
Docs
Union type : https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html#union-type
Type Guard: https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html
UPDATE
As requested, if one does want to test for the interface one needs to create a user defined type guard (docs https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html#user-defined-type-guards). Example:
function isMyInterface(foo:any): foo is IMyInterface {
return typeof foo.doC === 'function';
}
class Factory {
myClass: Common | IMyInterface;
doSomething() {
const myClass = this.myClass;
if (isMyInterface(myClass)){
// works!
myClass.doC('test');
}
}
}
So complete code becomes :
class IMyInterface {
doC:(any) => any;
}
class Common {
commonProperty:any;
doA() {
}
doB() {
}
}
class ClassA extends Common {}
class ClassB extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class ClassC extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class ClassD extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
class ClassE extends Common implements IMyInterface {
doC(test:any) {
return true;
}
}
function isMyInterface(foo:any): foo is IMyInterface {
return typeof foo.doC === 'function';
}
class Factory {
myClass: Common | IMyInterface;
doSomething() {
const myClass = this.myClass;
if (isMyInterface(myClass)){
// works!
myClass.doC('test');
}
}
}