I have two classes interfaceTestA and interfaceTestB. They have
an arraylist called 'myList' and a method, 'makeString()' in commom.
MyList is defined in an interface named hasList and makeString is
implemented in an abstract class getTheData. So both of them extend
getTheData and implement hasList. Compiling and running, for example,
interfaceTestA works just fine. In particular it has access to myList.
But now, in a class called ifTest, I want to instantiate one of the
two known only at run time. My problem is that when instantiated
this way, it does not know about myList. See the listings.
import java.util.*;
interface hasList { ArrayList myList = new ArrayList(); }
//===
abstract class getTheData {
public String makeString() { return "Hi Mom"; }
}
//===
public class
interfaceTestA extends getTheData implements hasList
{
public interfaceTest() {
setString();
System.out.println("size= "+myList.size());
}
void setString() { myList.add(makeString()); }
public static void main(String[] args) {
interfaceTestA it = new interfaceTestA();
}
}
import java.util.*;
import java.lang.reflect.*;
public class
ifTest
{
public static void
main(String[] args)
{
Class prog = Class.forName("interfaceTestA");
getTheData gtd = (interfaceTestA) prog.newInstance();
System.out.println("myList size= "+gtd.myList.size());
}
}
interfaceTestA is child of hasList but getTheData is not. In your code, type of gtd is getTheData so that it can not see the myList.
I found a solution. Create a new abstract class that combines both, e.g. abstract class combined extends getTheData implements hasList. Now
declare gtd to be of type combined, e.g. combined gtd = (interfaceTestA)prog.newInstance().
And it now works. Thanks for the help.
Related
I'm learning abstract classes vs interfaces at the moment and trying to figure out situations where to use one over the other. I'm having trouble figuring out this example at the moment:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("over here");
}
}
public class Thing extends Tract implements Face {
public void test() {
// what should print out?
}
}
Here, the test() function is implemented in the abstract class. If you don't implement it in the subclass, would it call the abstract class' method and print out "over here"? Does the interface accept implementations from an ancestor class or do you have to implement it in the subclass, therefore overriding the abstract class implementation?
All the interface cares about is that the class has implemented a method called test() that returns void. It does not matter whether the method is implemented in the class directly or in any ancestor (parent) class.
In your case, the Thing class has inherited its definition of test() from Tract, and therefore implements the Face interface without you having to provide a definition explicitly.
In the class "Tract" you have given an implementation for the method coming from the interface. Also you override it in "Thing" class so when calling this method on a Thing instance then this version(Thing version) is going to be called.
All java methods are virtual.
lets consider little bit modified code,
I hope, you will get the idea:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("Tract here");
}
}
public class Thing extends Tract implements Face {
public void test() {
System.out.println("Thing here");
}
}
public class Thing2 extends Tract implements Face {
}
lets go to output:
Tract tr = new Tract();
tr.test();
will not compile because you can't instantiate abstract class.
Thing th = new Thing();
th.test();
will print "Thing here"
Thing2 th2 = new Thing2();
th2.test();
will print "Tract here",
because you not overwritten the test() method in abstract class.
Main idea of this approach - you can abstract implementation in the future use
class C {
void print(Face face) {
face.test();
}
}
new C(new Thing()).print();
will print "Thing here";
new C(new Thing2()).print();
will print "Tract here";
You can hide different implementations
But this is not main idea of abstract classes.
main idea abstract classes are:
public interface Face {
public void test();
}
public abstract class Abstract {
abstract public void test();
}
public class Thing1 extends Abstract implements Face {
public void test() {
System.out.println("Thing1 here");
}
}
public class Thing2 extends Abstract implements Face {
public void test() {
System.out.println("Thing2 here");
}
}
main idea - you can declare method without implementation
new C(new Thing1()).print();
will print "Thing1 here";
new C(new Thing2()).print();
will print "Thing2 here";
main idea - you declare the method in abstract class, that you MUST override to compile code.
I hope, this is enough explained answer.
so I have an abstract class and i'm willing to store all the values from the sub-classes in an ImmutableList. Here is an example on what I mean
public abstract class Test {
...
public abstract int getValue();
}
then the sub-class
public final class Example extends Test {
#Override
public int getValue() {
return 5;
}
}
Is there a way to store the Test#getValue() in an ImmutableList on start-up?
I tried doing something like
public abstract class Test {
public static final ImmutableList<Integer> VALUES = ImmutableList.of();
public Test() {
VALUES.add(getValue());
}
public abstract int getValue();
}
then print out the values in the VALUES list.
public static void main(String[] args) {
Test.LIST.forEach(System.out::println);
}
but it didnt work.
use an initializer block. It's possible to create a static block which will execute upon class load:
package foo.bar.baz;
import java.util.*;
public class Test {
static {
int MY_INT = 5;
List<Object> mylist = new ArrayList<Object>();
mylist.add(new Integer(MY_INT));
}
public Test() {
// ...
}
}
You can write in the main method like this :
Reflections reflections = new Reflections("com.TestClassExample");
Set<Class<? extends >> classes = reflections.getSubTypesOf(TestExampleClass.class);
Get all the names of the classes and then loop through all the classes, and then cast it in the your test class and , then using and storing the values dynamically in a variable like this.
private static List<Integer> immutableList = new ArrayList<Integer>();
Does this sound feasible for your problem ?
I have my subclass:
public class Actions extends Main{
public void getFireTarget() {
GameObject target = getGameObjects().closest("Target");
do{
log("Shooting at the target");
getMouse().click(target);
} while(target != null && !getDialogues().inDialogue() && getLocalPlayer().getTile().equals(rangeTile));
}
}
I want to write similar methods, so I can call them in my Main class, so I don't have to write over and over.
My main class looks like this (won't fully paste it as it's long):
public class Main extends AbstractScript{
...code here
Actions actions = new Actions();
}
So I am trying to implement the methods in Actions by doing actions.getFireTarget(), which seems to work. But when I compile, I am getting two compile errors:
1) In the Main class, in the line: Actions actions = new Actions();
2) In the Actions class, in the line where I am extending the superclass.
Am I missing something in the sub class in order to store methods and then call them in the main method? Please advise! Thanks
The syntax is wrong. () are not allowed here: public class SomeName(). Remove the brackets.
I am having trouble understanding your details.
Here is a short info about inheritance:
public class A{
protected int t;
public void methodA(){}
}
public class B extends A{
#Override
public void methodA(){}
public void methodB(){}
}
If you override the methodA in class B, any call from a instance of class B to the method will use the method defined in class B. (If you dont write the method in class B, it will use the method from class A)
Objects of class A cannot use methodB() defined in class B.
Also you can access the field t in class B, because of the protected modified.
I think its better for you your problem to instantiate other class to your main class if you have same function name or same variable name. try to compile and run this code
public class First{
Second sec = new Second();
String s = "This is first";
public First(){
System.out.println(this.s);
System.out.println(getSecondString());
System.out.println(sec.getSecondString());
}
public String getSecondString(){
return "This is first";
}
public static void main(String args[]){
new First();
}
}
public class Second {
String s = "This is second";
public String getSecondString(){
return s;
}
}
Could someone explain in the following example why the interface method can be called directly when it is passed as a parameter in a class constructor? I try to search a rule in the Java language specification but can not find one.
public interface Interface {
public void foo();
}
public class Main {
public Main() {}
public Main(Interface obj) {obj.foo();}
public static int test() {return 123;}
}
Is just a polymorphic behaviour, Java expects an implementation of the method of that interface.
That means, any class which implements that method is an Interface, so you can have many many different implementations of that method.
Let's say:
public class ImplementedInterface implements Interface
{
public void foo()
{
System.out.println("Hey!, i'm implemented!!");
}
}
So when you call:
Interface aux = new ImplementedInterface();
Main m = new Main(aux);
The text "Hey!, i'm implemented!!" will be printed.
You can call foo method from Interface reference because it can hold only object of class that implements Interface, so it will provide body for foo method.
Now thanks to late binding Java will use code of object class when needed.
I think that you are confused, you think cuase it's Interface type it's an interface
public Main(Interface obj) {
obj.foo();
}
obj is an object from a concrete implementation of Interface.
You may want to see some common design pattern that take this approach such as Strategy Pattern
For example :
public interface Searcher {
void search(String text, List<String> words);
}
public class BinarySearcher implements Searcher{
#Override
public void search(String text , List<String> words){
//code here
}
}
public class LinearSearcher implements Searcher{
#Override
public void search(String text ,List<String> words ){
// code here
}
}
public class WordContext {
private Searcher searcher;
private List<String> words;
public void makeSearch(String text){
searcher.search(); // you only know at runtime what subtype will be searcher
}
// here you inject by contract
public void setSearcher(Searcher searcher){
this.searcher= searcher;
}
// here you inject by contract
public void setWords(List<String> words){
this.words = words;
}
}
That's the main advantage you guide by abstract contract instead of concrete implementation.
In this example you can change the searcher injecting it, can be a linearSearcher or a binarySearcher, that's the polymorphic magic!
Here is where Programming to an interface, not an implementation comes into play. Your method is expecting an object of the class that that implements the interface
I would explain it with an example.
Let us say I have
LinkedList<String> ll = new LinkedList<String>();
and I have
ArrayList<String> al = new ArrayList<String>();
Now I have a method -
public void deleteFirst(List aList) {
System.out.println(aList.remove(0));
}
Now you can pass both ll and al to the deleteFirst method. Which means your method is passed an object of the class that that implements the interface.
In the example ArrayList and LinkedList both implement the List interface and therefore can be passed to the method. Ultimately what your method is getting is an object of the class that implements the List interface.
Assume there is a code as such:
package com.ps.Sample;
public interface Sample
{
public void Method1();
}
public abstract class AbstractSample implements Sample
{
public void Method1()
{
System.out.println("Hello World");
}
}
public class MySample extends AbstractSample
{
}
public class TestSample
{
public static void main(String[] args)
{
Sample my = new MySample();
my.Method1();
}
}
My question is:
Is there any benefit to declaring the concrete class as
public class MySample extends AbstractSample implements Sample
instead of
public class MySample extends AbstractSample
No, there is not. It's redundant. AbstractSample is a Sample, and MySample is a AbstractSample. So MySample is a Sample.
The javadoc displays all the implemented interfaces anyway, whether you add the implements Sample or not.
One benefit would be that if AbstractSample was changed to not implement Sample, the first declaration would still allow you to pass instances of MySample to methods expecting a Sample.