How Cast to unknow class - java

I have a class:
public class Example {
public String name;
}
but this class does not have to be called Example may be different(like Example2, AnotherExample I don't know how), the problem is that I do not know how to be called.
In another class I have a method which take as parameter a list of objects.
My Example class:
public class ObjectClass{
public List<Object> doSomething(List<Object> objects) {
for(int i = 0 ; i < objects.size();i++) {
Class<?> c = objects.get(i).getClass();
System.out.println("class name " + c.getCanonicalName());// i get name my class
System.out.println(((Example) objects.get(i)).name);
}
}
}
When I change the cast Example to another class like this System.out.println(((c) objects.get(i)).name);
it doesn't work.
My class can call itself differently then cast to Example will not work.
Generally speaking I want get value of name, while not knowing how the class is named. But I select which class with a field name(or by having an annotation).
Edit: is one problem, it is my homework and i can't change class Example, and i can't change method doSomething.

If you look specifically after a field name, you can also iterate over all fields via reflection and access the right one.
public List<Object> doSomething(List<Object> objects) {
for (int i = 0; i < objects.size(); i++) {
Class<?> c = objects.get(i).getClass();
for (Field field : c.getFields()) {
if ("name".equals(field.getName())) {
try {
System.out.println("class name " + c.getCanonicalName());// i get name my class
System.out.println(field.get(objects.get(i)));
} catch (Exception e) {
}
}
}
}
return null;
}

Welcome to the wonderful world of polymorphism. Here is what you can do:
interface Named
{
String getName();
}
public class Example implements Named
{
public String name;
#Override
public String getName()
{
return name;
}
}
public class AnotherExample implements Named
{
public String name;
#Override
public String getName()
{
return name;
}
}
then you can do this:
System.out.println(((Named) objects.get(i)).getName());
then of course I would also recommend that you do the following:
public List<Named> doSomething(List<Named> objects) {
so that then you can do this:
System.out.println(objects.get(i).getName());
Edit after clarification:
If you cannot add your own interface, then try something like this:
Object foo = objects.get(i);
if( foo instanceof Example )
{
Example example = (Example)foo;
...do something with example...
}
else if( foo instanceof AnotherExample )
{
AnotherExample anotherExample = (AnotherExample)foo;
...do something with anotherExample...
}
else
{
assert false; //I do not know what class this is.
}

Related

Choosing between extended classes inside constructor

I am writing a java (processing) library for unexperienced students, and am looking for the best architecture for implementing it.
Initialization of an object should be as close as possible to this:
myObject = new General("type1");
Such that myObject will become an instance of Type1 which extends General:
class General {
public General() {}
}
class Type1 extends General {
public Type1() {}
}
class Type2 extends General {
public Type1() {}
}
As far as I know, this isn't possible (choosing between extended classes during initialization), but I'm looking for the closest solution possible.
So far, my best solution is to make a static initializer inside General:
class General {
...
static General init (String type) {
General temp;
if (type.equals("type1") {
temp = new Type1();
}
...
return temp;
}
and the initialization is:
General myObject;
myObject = General.init("type1");
This is far from ideal...
thanks.
you can make a factory class that manages initialization.
instead of doing it inside the parent.
// Empty vocabulary of actual object
public interface IPerson
{
string GetName();
}
public class Villager : IPerson
{
public string GetName()
{
return "Village Person";
}
}
public class CityPerson : IPerson
{
public string GetName()
{
return "City Person";
}
}
public enum PersonType
{
Rural,
Urban
}
/// <summary>
/// Implementation of Factory - Used to create objects.
/// </summary>
public class Factory
{
public IPerson GetPerson(PersonType type)
{
switch (type)
{
case PersonType.Rural:
return new Villager();
case PersonType.Urban:
return new CityPerson();
default:
throw new NotSupportedException();
}
}
}
The State design pattern can be a solution here. Rather than the constructor argument changing the type of the object (which isn't possible) it can set a field of the object, to make it behave as if its type is different.
package stackoverflow.questions;
public class Main {
private interface MyInterface {
String foo();
int bar();
}
private static class Type1 implements MyInterface {
#Override public String foo() { return "lorem ipsum "; }
#Override public int bar() { return 6; }
}
private static class Type2 implements MyInterface {
#Override public String foo() { return "dolor sit amet"; }
#Override public int bar() { return 7; }
}
public static class General {
private final MyInterface type;
public General(String type) {
try {
this.type = (MyInterface) Class
.forName("stackoverflow.questions.Main$" + type)
.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Invalid type: " + type);
}
}
public String method1() { return type.foo(); }
public int method2() { return type.bar(); }
}
public static void main(String... args) {
General one = new General("Type1");
General two = new General("Type2");
System.out.println(one.method1() + two.method1());
System.out.println(one.method2() * two.method2());
}
}

How to access a parent class variable via a child class

I am trying to re-build an OOP approach to mobile verification at the developers discretion. The concept I come up with is to allow for interfaces to manipulate the class. If the class implements the interface, then the verify method will be executed.
The problem I am facing, because I am only used to programming in less strongly-typed languages (PHP) is how to get a protected variable from a class extending the current class.
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
This line of code is now giving me an error
_mobileNumber cannot be resolved or is not a field
Here is my full code and here is an example I wrote of the same concept in PHP which I am trying to implement in Java.
import java.util.ArrayList;
interface Verification
{
public void initVerification();
}
class AreaCode
{
private int _code;
private String _country;
public AreaCode(int code, String country)
{
this._code = code;
this._country = country;
}
public int getAreaCode() { return this._code; }
public String getAreaCountry() { return this._country; }
}
class VerificationHandler
{
private ArrayList<AreaCode> _areaCodes = new ArrayList<AreaCode>() {{
this.add(new AreaCode(44, "UNITED KINGDOM"));
this.add(new AreaCode(91, "INDIA"));
}};
public void initVerification()
{
if(this instanceof Verification) {
this.verify();
}
}
protected void verify()
{
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
}
}
class Main extends VerificationHandler implements Verification {
protected String _mobileNumber = "+447435217761";
}
public class Hack1337 { public static void main(String[] args) { new Main(); } }
How can I retrieve a variable in a class extending another, ie:
class A { public String getB() { return this.b; } }
class B extends A { protected String b = 'A should get this'; }
B b = new B().getB();
Only instances of class B, or sub-classes of B can access the b instance variable directly (unless you cast A to B within the body of the A class, which is bad practice).
You can give class A read-only access to that value by overriding getB():
class B extends A
{
protected String b = 'A should get this';
#Override
public String getB() {
return this.b;
}
}
and you may also want to make the getB() method abstract in class A (which means making class A abstract):
abstract class A
{
public abstract String getB();
}
This would only make sense if different sub-classes of A are expected to return different things in getB(). Otherwise, you may as well move the b variable to the base class A.

how to see the class name containing the actual code

package a;
public class A {
public String toString() {
// return "I am an a.A"; is too primitive ;)
return "I am an " + getClass().getName(); // should give "a.A"
}
}
--
package a;
public class X extends A {
public static void main(String[] args) {
X test = new X();
System.out.println(test); // returns "I am an a.X"
}
}
I also tried with this.getClass() and super.getClass(). How can I get the class name of where toString() and getClass() is coded actually ? (a.A)
This is just a simplified sample, my point is how to avoid hard coding the base class name in the first file (A.java)
package a;
public class A {
public String toString() {
return "I am an " + A.class.getName();
}
}
should do the trick.
Change :
getClass().getName()
into
A.class.getName()
just iterate over all super
public String toString() {
Class cl = getClass();
while (cl.getSuperclass() != Object.class)
cl = cl.getSuperclass();
return cl.getName();
}

How to read and write to variables of an abstract class

Put simply, I have an abstract class containing several variables and methods. Other classes extend this abstract class, yet when I try to read the private variable in the abstract class by calling getter methods inside the abstract class, it returns null as the value of the variable.
public class JavaApplication {
public static void main(String[] args) {
NewClass1 n1 = new NewClass1();
NewClass2 n2 = new NewClass2();
n1.setVar("hello");
n2.print();
}
}
public class NewClass1 {
public String firstWord;
public void setVar(String var) {
firstWord = var;
}
public String getVar () {
return firstWord;
}
}
public class NewClass2 extends NewClass1{
public void print() {
System.out.println(makeCall());
}
public String makeCall() {
return getVar();
}
}
Still prints out null.
Until the String is initialized, it will be null. You should probably have a constructor in the abstract class to set it.
public abstract class Command
{
String firstWord; // = null
protected Command(){}
protected Command( String w )
{
firstWord = w;
}
//...
}
public class Open extends Command
{
public Open()
{
this( "your text" );
}
public Open( String w )
{
super( w );
}
// ...
}
If you need to modify the firstWord string everytime execute() is called then it may not be necessary to use a constructor with a String parameter (I added a default constructor above). However, if you do it this way then either
You must make sure setFirstWord() is called before getFirstWord(), or,
Handle the case when getFirstWord() returns null. This could be by simply using a default value (maybe determined by each subclass) or something else, like failing to execute.
As I do not know all the details of your implementation I cannot tell you further information.

using equals or instanceof in toString

Ok guys I have a program with a 'MartianManager' class: *Note code is not complete still have some missing pieces just supplied entire code for reference of somewhat how it is going to look when complete
import java.util.ArrayList;
public class MartianManager {
private ArrayList<Martian> martians;
private ArrayList<Martian> teleporters;
public void addMartian(Martian m) {
martians.add(m);
if(m instanceof GreenMartian)
teleporters.add(m);
}
//public Object clone() {
public Martian getMartianClosestToID(int id) {
}
public void groupSpeak() {
for(Martian m : martians) {
m.speak();
}
}
public void groupTeleport(String dest) {
}
}
and Martian class:
public abstract class Martian implements Cloneable {
int id;
public Martian(int id) {
this.id = id;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public int getId() {
return id;
}
public boolean equals(Object o){
return this.getId() == ((Martian)o).getId();
}
public abstract void speak();
public String toString(){
String str = "";
if (this instanceof GreenMartian) {
str = "Green martian" + id;
}
if (this instanceof RedMartian) {
str = "Red martian" + id;
}
return str;
}
}
it is extended with GreenMartian:
public class GreenMartian extends Martian implements ITeleport{
public GreenMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Grobldy Grock");
}
public void teleport(String dest) {
System.out.println(id + "teleporting to " + dest);
}
}
also extended with RedMartian:
public class RedMartian extends Martian {
public RedMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Rubldy Rock");
}
}
I actually have a few questions , but for now my question is in the toString of the Martian class. It should return a string like this: "Red [or Green] martian" +id. I need to determine the type of Martian, I started to use the instanceof but like this "Martian couldn't be resolved to a variable". I'm trying to determine if this would be the best way or if an equals() would be the best way to determine the type?
Also this is my first time using "clone" so not sure how it works exactly, but had a thought is there a way to determine what the "clone" was and determine it that way?
Thanks for any and all help!
No
public String toString(){
String str;
if (Martian instanceof GreenMartian) {
}
in abstract Martian class is a bad idea. You don't want your parent class to depend on its children.
Implement a toString() method in each subclass instead and let polymorphism do its work.
If you absolutely have to
if (Martian instanceof GreenMartian) {
is wrong. You use instanceof as so
instanceOfClass instanceof SomeClass
In this case you get a reference to instanceOfClass with the this keyword, since you are calling the method on an instance
this instanceof GreenMartian
You really should not have a parent class reference any classes that extend it. This is bad practice (and might not actually work, i haven't tested). You should really just override the toString function in each extended class.
public class GreenMartian extends Martian implements ITeleport{
public GreenMartian(int id) {
super(id);
}
public void speak() {
System.out.println(id + "Grobldy Grock");
}
public void teleport(String dest) {
System.out.println(id + "teleporting to " + dest);
}
#Override
public String toString() {
return "GreenMartian: whatever info you'd like to include.";
}
}
Now, if you want to have a similar format for all subclasses, you have two options. One is to call the toString method of the parent class, and prepend that to the subclass's toString method.
#Override
public String toString() {
return super.toString() + "GreenMartin: info.....";
}
//The parent toString could look like this:
#Override
public String toString(){
return "Martian( ... put any parent class info here, id ect)";
}
The final output for a GreenMartian toString call then may look like this:
Martian(id:23) GreenMartian(planet:greenburg)
A Third option would be to have a common string format in the parent class. For example, in the parent class, include this attribute:
protected static final String format = "Class: %s, id: %s, info: %s";
Then, in the subclass toString, you can do this:
#Override
public String toString() {
return String.format(format,this.getClass().toString(),id,myInfo);
}
You can use String name = this.getClass().getSimpleName() to get the name of your class. Then you can check name.substring(0,1).equals("G") or name.substring(0,1).equals("R") to detect Red or Green.
FWIW, it should be if (this instanceof GreenMartian) - but IMHO whenever you are tempted to use such an downcast (upcast??), it is an sign of bad OO design. Rather write a specialized toString()method for your martians. And you should really check for o==null in your equals() method.
Martian is not a variable. Try this instead:
if(this instanceof GreenMartian)

Categories

Resources