I have two classes that do the same things but by the different ways. I need to create an object of one of these classes depending on config settings. Here is a brief example of what do I want to do.
public class A {
public string getLetter() {
return "A";
}
}
public class B {
public string getLetter() {
return "B";
}
}
public class MainActivity {
private myObject; // How to declare it in my case?
private int config = 0;
public void onCreate(Bundle savedInstanceState) {
if (config == 0) {
myObject = new A();
} else {
myObject = new B();
}
String letter = myObject.getLetter();
}
}
Actually everything is much more complex. Each of classes A and B asynchronously listens to the different sources of data, converts it to the format that can be used in further processing and passes it to MainActivity. Depending on configuration only one source of data must be selected. How can I do this? Variant with
letter = A.getLetter();
will not work.
This should work:
public class A {
public String getLetter() {
return "A";
}
}
public class B {
public String getLetter() {
return "B";
}
}
public class MainActivity {
private int config = 0;
public void onCreate(Bundle savedInstanceState) {
String letter="";
if (config == 0) {
A myObject = new A();
letter = myObject.getLetter();
} else {
B myObject = new B();
letter = myObject.getLetter();
}
}
}
Use interface or abstract class and implement or extend it in class A and B, e.g.
public interface Letter {
String getLetter();
}
public class A implements Letter {
public String getLetter() {
return "A";
}
}
public class B implements Letter {
public String getLetter() {
return "B";
}
}
// Then you can declare and use it as interface
private Letter myObject;
// init logic
...
String letter = myObject.getLetter();
Related
I decided to get into more JAVA and I noticed in OCA 7 that an enum can declare a method which overrides another method. See this enum:
enum CoffeeSize {
BIG(),
HUGE(),
OVERWHELMING() {
public String getLidCode() { // This method overrides the following method with similar name.
return 'A';
}
}; // <--- is this semicolon I should be looking for?
CoffeeSize(ounces) {
this.ounces = ounces;
}
private int ounces;
public int getOunces() {
return ounces;
}
public String getLidCode() {
return 'B';
}
}
My question is in which case does a method in a enum override another method. Is it the method preceding the semicolon that overrides or what's the rule here?
Thanks for your time.
The constants act similar to anonymous classes, where the enum itself is the abstract base class:
abstract class CoffeeSize {
CoffeeSize(int ounces) {
this.ounces = ounces;
}
private int ounces;
public int getOunces() {
return ounces;
}
public String getLidCode() {
return "B";
}
}
CoffeeSize OVERWHELMING = new CoffeeSize(3) {
#Override
public String getLidCode() {
return "A";
}
};
You can override the base implementation with any constant, not just the one before the semicolon:
enum CoffeeSize {
BIG(1){
#Override
public String getLidCode() {
return "C";
}
},
HUGE(2) {
#Override
public String getLidCode() {
return "B";
}
},
OVERWHELMING(3) {
#Override
public String getLidCode() {
return "A";
}
};
...
}
In the above, all the constants override getLidCode with a different implementation. The semicolon just marks the end of the list of constants.
I'm trying to figure out why i keep getting the error that my AM class does not override abstract method. In my teachers UML diagram it only shows that i need the equals (Object o) method in my parent radio class. Also i'm not declaring it as abstract in my abstract class.
public abstract class Radio implements Comparable
{
double currentStation;
RadioSelectionBar radioSelectionBar;
public Radio()
{
this.currentStation = getMin_Station();
}
public abstract double getMax_Station();
public abstract double getMin_Station();
public abstract double getIncrement();
public void up()
{
}
public void down()
{
}
public double getCurrentStaion()
{
return this.currentStation;
}
public void setCurrentStation(double freq)
{
this.currentStation = freq;
}
public void setStation(int buttonNumber, double station)
{
}
public double getStation(int buttonNumber)
{
return 0.0;
}
public String toString()
{
String message = ("" + currentStation);
return message;
}
public boolean equals (Object o)
{
if (o == null)
return false;
if (! (o instanceof Radio))
return false;
Radio other = (Radio) o;
return this.currentStation == other.currentStation;
}
public static void main(String[] args)
{
Radio amRadio = new AMRadio();
System.out.println(amRadio);
Radio fmRadio = new FMRadio();
System.out.println(fmRadio);
Radio xmRadio = new XMRadio();
System.out.println(xmRadio);
}
}
public class AMRadio extends Radio
{
private static final double Max_Station = 1605;
private static final double Min_Station = 535;
private static final double Increment = 10;
public AMRadio()
{
currentStation = Min_Station;
}
public double getMax_Station()
{
return this.Max_Station;
}
public double getMin_Station()
{
return this.Min_Station;
}
public double getIncrement()
{
return this.Increment;
}
public String toString()
{
String message = ("AM " + this.currentStation);
return message;
}
}
You have to implement the compareTo() method, given that Radio implements the Comparable interface and a concrete implementation for this method wasn't provided in the Radio class, so you have two choices:
Implement compareTo() in all of Radio's subclasses
Or implement compareTo() in Radio
Something like this, in AMRadio:
public int compareTo(AMRadio o) {
// return the appropriate value, read the linked documentation
}
Or like this, in Radio:
public int compareTo(Radio o) {
// return the appropriate value, read the linked documentation
}
This is a practical question, but I am not sure if it has a practical answer. If you have a superclass with let's say 10 subclasses, what is the most simple way to put those 10 subclasses in a collection? Right now (this may be bad design), I have put them in a static collection field in the superclass.
The motivation for this question, however, came because I had obtained the identity of one of the fields of one of the subclasses, but I needed a reference to a different field in the same subclass.
For instance, let's say the subclass has the following fields:
public class SampleSubClass extends SampleSuperClass{
...
private Object1 o_1;
private Object2 o_2;
private Object3 o_3;
...
}
Somewhere else in the program, I have only the identity of o_2, and I wanted to get at o_3.
In theory, there might be an easier way than having to put all of the instances of SampleClass in a collection somewhere. For instance, perhaps in my dreams, there is a software language out there, where the superclass DOES carry information about its subclasses, and the superclass serves as a collection in and of itself.
But nevermind that. To me now, it seems like a good way to put the collection somewhere in the program, is to use a hashmap/hashtable, and to use it as a static member of the superclass.
Please tell me there is a better way. Is there any way to reference field A in an object by having only a reference to field B in an object?
For instance, say I have an ActionPerformed method, it has a source object that is contained in the ActionEvent object parameter. How would I find the instance of the class that owned/contained that source object? What is the best way to design this?
There is no native way to find the owner of a field given the object the field references. The JVM records the number of references pointing to each object so it can do garbage collection, but it doesn't keep track of the owners of the references.
You can store the values of all the fields in a Map which maps them to their owners:
import java.util.*;
public class Super
{
static Map<Object, Super> owners = new IdentityHashMap<Object, Super>();
// IdentityHashMap will not work with primitives due to autoboxing,
// but HashMap requires all field values to have sensible implementations
// of hashCode() and equals().
/** Gets the owner associated with a field. */
public static Object getOwner(Object field)
{
return owners.get(field);
}
/** Establishes ownership over a field. */
protected void own(Object field)
{
owners.put(field, this);
}
/** Removes an ownership, but only if this is the owner. */
protected void disown(Object field)
{
if (owners.get(field) == this) owners.remove(field);
}
/** Shorthand for disown(oldField); own(newField). */
protected <T> T change(T oldField, T newField)
{
disown(oldField);
own(newField);
return newField;
}
}
public class SubA extends Super
{
protected String s;
protected Integer i;
public SubA(String aString, Integer anInt) { setS(aString); setI(anInt); }
public void setS(String aString) { s = change(s, aString); }
public void setI(Integer anInt) { i = change(i, anInt); }
public String toString() { return "SubA(" + s + "," + i + ")"; }
}
public class SubB extends Super
{
protected Object o;
public SubB(Object anObject) { setO(anObject); }
public void setO(Object anObject) { o = change(o, anObject); }
public String toString() { return "SubB(" + o + ")"; }
}
public class Demo
{
public static void main(String[] args)
{
String s1 = "String1", s2 = "String2", s3 = "String3";
Integer i1 = 111, i2 = 222;
Object o1 = new Object(), o2 = new Object();
SubA a1 = new SubA(s1, i1), a2 = new SubA(s2, i2);
SubB b = new SubB(o1);
p("s1 owner = %s", Super.getOwner(s1)); // SubA(String1,111)
p("s2 owner = %s", Super.getOwner(s2)); // SubB(String2,222)
p("s3 owner = %s", Super.getOwner(s3)); // null
p("i1 owner = %s", Super.getOwner(i1)); // SubA(String1,111)
p("i2 owner = %s", Super.getOwner(i2)); // SubA(String2,222)
p("o1 owner = %s", Super.getOwner(o1)); // SubB(java.lang.Object#...)
p("o2 owner = %s", Super.getOwner(o2)); // null
p("s1 -> s3, o1 -> o2");
a1.setS(s3);
b.setO(o2);
p("s1 owner = %s", Super.getOwner(s1)); // null
p("s3 owner = %s", Super.getOwner(s3)); // SubA(String3,111)
p("o1 owner = %s", Super.getOwner(o1)); // null
p("o2 owner = %s", Super.getOwner(o2)); // SubB(java.lang.Object#...)
}
static void p(String fmt, Object... args)
{
System.out.format(fmt, args);
System.out.println();
}
}
Or you could make the field values themselves maintain a reference to their owner, either through inheritance or using a wrapper class:
public class OwnableObject
{
protected Object owner;
public OwnableObject(Object anOwner) { owner = anOwner; }
public Object getOwner() { return owner; }
public void setOwner(Object anOwner) { owner = anOwner; }
}
public class MyString extends OwnableObject
{
protected String str = null;
public MyString(Object anOwner) { super(anOwner); }
public String toString() { return str; }
public void set(String aString) { str = aString; }
}
public class FieldWrapper<E> extends OwnableObject
{
protected E value = null;
public FieldWrapper(Object anOwner) { super(anOwner); }
public E getValue() { return value; }
public void setValue(E aValue) { value = aValue; }
}
public class Demo
{
protected MyString s = new MyString(this);
protected FieldWrapper<Integer> i = new FieldWrapper<Integer>(this);
public void setS(String aString) { s.set(aString); }
public void setI(int anInt) { i.setValue(anInt); }
public String toString() { return "Demo(" + s + "," + i.getValue() + ")"; }
public static void main(String[] args)
{
Demo d1 = new Demo();
Demo d2 = new Demo();
MyString f1 = d1.s;
FieldWrapper<Integer> f2 = d1.i;
OwnableObject f3 = d2.s;
OwnableObject f4 = d2.i;
d1.setS("one");
d2.setS("two");
d1.setI(1000);
d2.setI(2000);
p("f1 = %s, owner = %s", f1, f1.getOwner());
p("f2 = %d, owner = %s", f2.getValue(), f2.getOwner());
p("f3 = %s, owner = %s", f3, f3.getOwner());
p("f4 = %s, owner = %s", f4, f4.getOwner());
}
static void p(String fmt, Object... args)
{
System.out.format(fmt, args);
System.out.println();
}
}
Answering your direct question: how to easily define a collection containing a given set of classes?
public class ClassA {
private final List<Class<? extends a>> knownSubclasses = Arrays.asList(ClassB.class, ClassC.class);
};
class ClassB extends ClassA {}
class ClassC extends ClassA {}
Answering your motivation: how to access a field in a subclass without declaring it for the super class?
public class SomeSuperclass {
protected Object3 getObject3() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
}
public class SomeSubclass extends SomeSuperclass {
private final Object3 object3 = null;
#Override
protected Object3 getObject3() { return object3; }
}
Maybe recognize instances having an object3 by the use of interfaces
public interface MyClassWithObject3 { Object3 getObject3(); }
...
void someOperation(SomeSuperclass that) {
if (that instanceof MyClassWithObject3) { ... }
}
You could also use named properties
void someOperation(SomeSuperClass that) {
Object3 object3 = that.getProperty("object3");
}
I have an object that delegates some work to another object which is implementing an interface. Then, I am creating anonymous classes implementing this interface and I would like to get information from these.
Is it okay to use a final array with a size of one as a pointer to a primitve to share data with the anonymous class?
Here is a working example of what I mean :
public class ExampleClass
{
public static final int INVALID_VALUE = -1;
public static void main(final String[] args)
{
final int[] buffer = { INVALID_VALUE }; // buffer is created
final InterfaceA iaObject = new InterfaceA()
{
#Override
public void doStuff(final String paramA)
{
buffer[0] = paramA.length(); // buffer is filled in anonymous class
}
};
final ClassA objA = new ClassA(iaObject);
objA.doStuff("hello, world");
if (buffer[0] == INVALID_VALUE) // buffer is used
{
System.err.println("Invalid length !");
}
else
{
System.err.println("The length is : " + Integer.toString(buffer[0]));
}
}
public static class ClassA
{
private final InterfaceA iaObject;
public ClassA(final InterfaceA iaObject)
{
this.iaObject = iaObject;
}
public void doStuff(final String paramA)
{
this.iaObject.doStuff(paramA);
}
}
public static interface InterfaceA
{
void doStuff(String paramA);
}
}
Thanks
Suggestion: why not using a generic for an out parameter?
interface InterfaceA {
public <T> void doStuff( String paramA, Holder<T> holder );
}
class Holder<T> {
public T t;
}
Full example:
public class ExampleClass
{
public static final int INVALID_VALUE = -1;
public static void main(final String[] args)
{
final InterfaceA< Integer > iaObject = new InterfaceA< Integer >() {
#Override
public Integer doStuff( String paramA, Holder<Integer> holder ) {
return holder.value = paramA.length();
}
};
final ClassA<Integer> objA = new ClassA<>( iaObject );
int result = objA.doStuff("hello, world", new Holder<>( INVALID_VALUE ));
if( result == INVALID_VALUE ) {
System.err.println("Invalid length !");
}
else {
System.err.println("The length is : " + Integer.toString( result ));
}
}
public static class ClassA<T> {
private final InterfaceA<T> iaObject;
public ClassA( final InterfaceA<T> iaObject_ ) {
this.iaObject = iaObject_;
}
public T doStuff( final String paramA, Holder<T> holder ) {
return this.iaObject.doStuff( paramA, holder );
}
}
public static interface InterfaceA<T> {
public T doStuff( String paramA, Holder<T> resultHolder );
}
public static class Holder<T> {
public T value;
public Holder( T value_ ) {
value = value_;
}
}
}
If I understand the gist of your question, you're wondering if it is good design principle to use a final array as a wrapper to share memory between an anonymous inner class and its enclosing class.
In my experience, this is a pretty poor way of sharing data between two objects. It is probably wiser to declare your interface differently. Either return an object or use a generic to specify what type you expect back from your anonymous class.
I think one of the largest problems with your approach is the lack of encapsulation - your InterfaceA implementation uses some "global" data holder (the array), and there is no way to prevent that this array can be used elsewhere, which in turn could lead to all kinds of problems (race conditions or whatever).
A cleaner way would be the definition of some separate class (or interface) with a getInt()-method or something similar.
I have been trying to figure out a way to tag several methods from my base class, so that a client class can call them by tag. The example code is:
public class Base {
public void method1(){
..change state of base class
}
public void method2(){
..change state of base class
}
public void method3(){
..change state of base class
}
}
A client class from a main() method will call each method of Base through a random instruction sequence:
public static void main(String[] args) {
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++){
char temp = sequence.charAt(i);
switch(temp){
case 'A':{aBase.method1(); break;}
case 'B':{aBase.method2(); break;}
case 'C':{aBase.method3(); break;} }
}
System.out.println(aBase.getState());
}
Now I wish to get rid of the switch statement altogether from the Client object. I am aware of the technique to replace switch by polymorphism, but would like to avoid creating a set of new classes. I was hoping to simply store those methods in an appropriate data structure and somehow tag them with a matching character from the sequence.
A map could easily store objects with value/key pairs which could do the job, (as I did here), or the command pattern, but since I don't want to replace those methods with objects, is there a different way perhaps, to store methods and have a client selectively call them?
Any advice is appreciated
Something like this?
public class Base {
private final Map<Character, Method> methods = new HashMap<Character, Method>();
public Base() throws SecurityException, NoSuchMethodException {
methods.put('A', getClass().getMethod("method1"));
methods.put('B', getClass().getMethod("method2"));
methods.put('C', getClass().getMethod("method3"));
}
public Method getMethod(char c) {
return methods.get(c);
}
public void method1() {}
public void method2() {}
public void method3() {}
}
and then
public static void main(String[] args) throws Exception {
String sequence = "ABCAABBBABACCACC";
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++) {
char temp = sequence.charAt(i);
aBase.getMethod(temp).invoke(aBase);
}
}
I would use annotations on the methods in question, allowing it to be marked as a "tagged method", and providing the tag string to use for that method.
From that point the implementation gets simpler; you can use reflection to iterate over a class' methods and inspect their annotations; perhaps do this statically at startup and populate a mapping from tag string to java.lang.reflect.Method.
Then when processing the command string, invoke the methods that correspond to each tag.
Edit: some example code:
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#interface TaggedMethod {
String tag();
}
Then in the base class:
public class Base {
#TaggedMethod(tag = "A")
public void method1(){
..change state of base class
}
#TaggedMethod(tag = "B")
public void method2(){
..change state of base class
}
#TaggedMethod(tag = "C")
public void method3(){
..change state of base class
}
}
...and in the client:
private static final Map<String, Method> taggedMethods = new HashMap<String, Method>();
// Set up the tag mapping
static
{
for (Method m : Base.class.getDeclaredMethods())
{
TaggedMethod annotation = m.getAnnotation(TaggedMethod.class)
if (annotation != null)
{
taggedMethods.put(annotation.tag(), m);
}
}
}
so that you can access this as:
public static void main(String[] args) throws Exception
{
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++)
{
String temp = sequence.substring(i,1);
Method method = taggedMethods.get(temp);
if (method != null)
{
// Error handling of invocation exceptions not included
method.invoke(aBase);
}
else
{
// Unrecognised tag - handle however
}
}
System.out.println(aBase.getState());
}
This code hasn't been compiled or tested, by the way... :-)
You could use Attributes for this, in C#. For Java, use annotations. Derive a class from the Attribute class, say, TagAttribute, and apply the attribute to the methods.
[global::System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class TagAttribute : Attribute
{
public TagAttribute(char value)
{
this.value = value;
}
private char value;
public char Value
{
get { return value; }
}
}
Apply the attribute to the methods:
public class MyClass
{
[Tag('A')]
public void Method1()
{ Console.Write("a"); }
[Tag('B')]
public void Method2()
{ Console.Write("b"); }
[Tag('C')]
public void Method3()
{ Console.Write("c"); }
}
Invoke the methods using reflection:
private static void CallTaggedMethod(MyClass instance, char value)
{
MethodInfo methodToCall = null;
// From the MyClass type...
Type t = typeof(MyClass);
// ...get all methods.
MethodInfo[] methods = t.GetMethods();
// For each method...
foreach (MethodInfo mi in methods)
{
// ...find all TagAttributes applied to it.
TagAttribute[] attributes = (TagAttribute[])mi.GetCustomAttributes(typeof(TagAttribute), true);
if (attributes.Length == 0)
// No attributes, continue.
continue;
// We assume that at most one attribute is applied to each method.
TagAttribute attr = attributes[0];
if (attr.Value == value)
{
// The values match, so we call this method.
methodToCall = mi;
break;
}
}
if (methodToCall == null)
throw new InvalidOperationException("No method to call.");
object result = methodToCall.Invoke(
// Instance object
instance,
// Arguments
new object[0]);
// 'result' now contains the return value.
// It is ignored here.
}
Call the CallTaggedMethod from your Main method:
static void Main(string[] args)
{
String sequence = "ABCAABBBABACCACC";
MyClass inst = new MyClass();
foreach(char c in sequence)
CallTaggedMethod(inst, c);
// The rest.
Console.ReadLine();
}
Here is my annotations Approach. You don't even need a Map of tags to methods if you are using annotations, just iterate over the sequence and lookup the method for that tag using reflection.
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Tag {
char value();
}
then:
public class Base {
StringBuilder state = new StringBuilder();
#Tag('A')
public void method1(){
state.append("1");
}
#Tag('B')
public void method2(){
state.append("2");
}
#Tag('C')
public void method3(){
state.append("3");
}
public String getState() {
return state.toString();
}
}
then
public final class TagRunner {
private TagRunner() {
super();
}
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Base b = new Base();
run(b, "ABCAABBBABACCACC");
System.out.println(b.getState());
}
private static <T> void run(T type, String sequence) throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
CharacterIterator it = new StringCharacterIterator(sequence);
Class<?> taggedClass = type.getClass();
for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
getMethodForCharacter(taggedClass, c).invoke(type);
}
}
private static Method getMethodForCharacter(Class<?> taggedClass, char c) {
for (Method m : taggedClass.getDeclaredMethods()) {
if (m.isAnnotationPresent(Tag.class)){
char value = m.getAnnotation(Tag.class).value();
if (c == value) {
return m;
}
}
}
//If we get here, there are no methods tagged with this character
return null;
}
}