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();
}
Related
I would like to add additional implementation to an overriding subclass method without completely overriding the superclass one. This is what I got to so far, but it doesn't seem to work. I would like the output to be "superclass return" followed by "subclass return". Here's the code:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
super.send();
return "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Output: subclass return
Am I using the wrong syntax super.send()? The intended output should be:
superclass return
subclass return
You have lost the return value of the super send() method and that is why you cannot see it in the output. To be able to see both, you need to modify the child implementation to something like this:
public String send() {
String value = super.send();
return value + "subclass return";
}
You aren't doing anything with the return value of the super class. Try this:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
return super.send() + "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Or if you want the line break:
return super.send() + "\nsubclass return";
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.
}
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)
I have a Java program that looks like this.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
What does LocalScreen.this means in aFuncCall?
LocalScreen.this refers to this of the enclosing class.
This example should explain it:
public class LocalScreen {
public void method() {
new Runnable() {
public void run() {
// Prints "An anonymous Runnable"
System.out.println(this.toString());
// Prints "A LocalScreen object"
System.out.println(LocalScreen.this.toString());
// Won't compile! 'this' is a Runnable!
onMake(this);
// Compiles! Refers to enclosing object
onMake(LocalScreen.this);
}
public String toString() {
return "An anonymous Runnable!";
}
}.run();
}
public String toString() { return "A LocalScreen object"; }
public void onMake(LocalScreen ls) { /* ... */ }
public static void main(String[] args) {
new LocalScreen().method();
}
}
Output:
An anonymous Runnable!
A LocalScreen object
This post has been rewritten as an article here.
It means the this instance of the outer LocalScreen class.
Writing this without a qualifier will return the instance of the inner class that the call is inside of.
The compiler takes the code and does something like this with it:
public class LocalScreen
{
public void method()
{
new LocalScreen$1(this).run;
}
public String toString()
{
return "A LocalScreen object";
}
public void onMake(LocalScreen ls) { /* ... */ }
public static void main(String[] args)
{
new LocalScreen().method();
}
}
class LocalScreen$1
extends Runnable
{
final LocalScreen $this;
LocalScreen$1(LocalScreen $this)
{
this.$this = $this;
}
public void run()
{
// Prints "An anonymous Runnable"
System.out.println(this.toString());
// Prints "A LocalScreen object"
System.out.println($this.toString());
// Won't compile! 'this' is a Runnable!
//onMake(this);
// Compiles! Refers to enclosing object
$this.onMake($this);
}
public String toString()
{
return "An anonymous Runnable!";
}
}
As you can see, when the compiler takes an inner class it converts it to an outer class (this was a design decision made a LONG time ago so that VMs did not need to be changed to understand inner classes).
When a non-static inner class is made it needs a reference to the parent so that it can call methods/access variables of the outer class.
The this inside of what was the inner class is not the proper type, you need to gain access to the outer class to get the right type for calling the onMake method.
Class.this allows access to instance of the outer class. See the following example.
public class A
{
final String name;
final B b;
A(String name) {
this.name = name;
this.b = new B(name + "-b");
}
class B
{
final String name;
final C c;
B(String name) {
this.name = name;
this.c = new C(name + "-c");
}
class C
{
final String name;
final D d;
C(String name) {
this.name = name;
this.d = new D(name + "-d");
}
class D
{
final String name;
D(String name) {
this.name = name;
}
void printMe()
{
System.out.println("D: " + D.this.name); // `this` of class D
System.out.println("C: " + C.this.name); // `this` of class C
System.out.println("B: " + B.this.name); // `this` of class B
System.out.println("A: " + A.this.name); // `this` of class A
}
}
}
}
static public void main(String ... args)
{
final A a = new A("a");
a.b.c.d.printMe();
}
}
Then you will get.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
I know what is your confusion.I am encounter the problem just now, it should have special scene to distinguish them.
class THIS {
def andthen = {
new THIS {
println(THIS.this.## + ":inner-THIS.this.##")
println(this.## + ":inner-this.##")
new THIS {
println(THIS.this.## + ":inner-inner-THIS.this.##")
println(this.## + ":inner-this.##")
}
}
}
def getInfo = {
println(THIS.this.## + ":THIS.this.##")
println(this.## + ":this.##")
}
}
You can see the diff between THIS.this and this in new THIS operation by hashcode( .## )
test in scala console :
scala> val x = new THIS
x: THIS = THIS#5ab9b447
scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1#181d7f28
scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##
THIS.this always point to outer THIS class which is refer by val x,but this is beyond to anonymous new operation.
Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}