Calling a super toString() method but using current class' variables - java

say we have 2 classes:
public class A {
private String name = "A";
public String toString()
{
return (name + "some random text");
}
}
public class B extends A{
private String name = "B";
public String toString()
{
return (super.toString());
}
}
When I tried to print the B.toString() in my driver class, it will still print the name from class A instead of the name from class B. How can I change it so it will use the variable name from class B instead?

You can do it through the use of constructors -
public class HelloWorld {
public static void main(String[] args) {
A a = new A("A String");
B b = new B("B String");
System.out.println(a.toString()); // A String some random text
System.out.println(b.toString()); // B String some random text
}
}
class A {
protected String name;
A(String name) {
this.name = name;
}
public String toString() {
return name + " some random text";
}
}
class B extends A {
B(String name) {
super(name);
}
#Override
public String toString() {
return (super.toString());
}
}
Because B inherits from A, the name field is setup correctly when you pass a string to the constructor for B.

Related

How to print name of object?

What I should change to print the name of chair, which is chairNumber1?
public class Employee {
private Chair s;
Employee(Chair s) {
this.s = s;
}
void showData() {
System.out.println("Name of chair : " + s);
}
}
public class Chair {
}
public class Hlavna {
public static void main(String[] args) {
Chair s = new Chair("chairNumber1");
Employee c1 = new Employee(s);
c1.showData();
}
}
Why when I want to print name of the Chair, which is chairNumber1, Java prints on console the address of chairNumber1, but not it's name?
You must be already aware of the fact that every class in Java inherits a class called Object by default. This class has a method toString() which returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
When you use System.out.println("Name of chair : " + s);, it will call s.toString() but since you haven't provided your own implementation of toString() inside class Chair, it will call the toString() method of class Object which is the default superclass of class Chair. This is why you see the value which you think as the address of chairNumber1.
To get your desired String, you need to override the toString() method something like:
public class Chair {
private String name;
public Chair(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
define a method inside your chair class that returns the name or override the toString method.
example:
public class Chair{
private String chairName;
Chair(String chairName){
this.chairName = chairName;
}
public String toString(){
return chairName;
}
}
now inside showdata() call toString():
void showData(){
System.out.println("Name of chair : " + s.toString());
}
There are a couple of things going on here.
You have created a chair object in your main method of your Hlavna class. To this Chair object you have provided an argument, although from the code above Chair does not take an argument.
In the same way that you have made the Employee class take an argument of chair, you should take the Chair take an argument of name, like so:
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
}
Now this isn't enough. When you print any Java object, under the hood what is really happening is the object's toString method is called. By default this prints the object's address, but you can override that by implementing the method yourself, like so:
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
public String toString()
{
return this.name;
}
}
Now, when you print a chair object it will call the Chair object's implementation of toString, which here returns the chair's name.
Your employee class is correctly printing the "toString()" method of the chair that you pass to it as you construct it, but currently that looks like an address. If you change the Chair object to the above code, that will instead print the chair name, which is what you are after.
The full code would look like this:
public class Employee
{
private Chair s;
Employee(Chair s)
{
this.s = s;
}
void showData()
{
System.out.println("Name of chair : " + s);
}
}
public class Chair
{
private String name;
Chair(String chairName)
{
this.name = chairName;
}
public String toString()
{
return this.name;
}
}
public class Hlavna
{
public static void main(String[] args)
{
Chair s = new Chair("chairNumber1");
Employee c1 = new Employee(s);
c1.showData();
}
}
public class Chair {
private String name;
public Chair(String name) {
this.name = name;
}
#Override
String toString() {
return name;
}
}

Input doesnt go all the way down to the children

I have a question about this code:
public class Musician {
private String name;
public String instrument;
public Musician(String name, String instrument){
this.name= name;
this.instrument= instrument;
}
public String getInstrument() {
return instrument;
}
public String getName() {
return name;
}
private String getClassName(){
return "Musician ";
}
public void play(){
System.out.println("[M] "+getClassName() + " plays music.");
}
public void printInfo(){
play();
System.out.println("[M] Class name: "+ getClassName());
System.out.println("[M] Instrument: "+ getInstrument());
}
}
public class RockMusician extends Musician{
public String instrument;
public RockMusician(String name, String instrument) {
super(name, instrument);
this.instrument= instrument + " and drums";
}
public String getClassName(){
return " RockMusician ";
}
public void play(){
System.out.println("[RM] "+ getClassName() + getName() + " breaks his "+ super.getInstrument() + "!");
}
}
public class IsraelyRockMusician extends RockMusician {
public IsraelyRockMusician(String name, String instrument) {
super(name, instrument);
}
public String getInstrument() {
return instrument;
}
public String getName(){
return super.getName() + " the king";
}
public String getClassName() {
return " IsraelyRockMusician ";
}
}
public class Testing {
public static void func(Musician m){
System.out.println("I've got a musician!");
}
public static void func(RockMusician m){
System.out.println("I've got a rock musician!");
}
public static void main(String[] args) {
Musician m3 = new IsraelyRockMusician("Chanoch", "guitar");
m3.printInfo();
}
}
I have IsraeliRockMusician who inherits RockMusician who Inherits Musician,
I then make a Musician m3 with the name "chanoch" and instrument "guitar"
and I active the method, print Info,
because the printInfo is in the father -> RockMusician which contains 3 methods on itself-> play(),getClassName(),and getInstrument(),
my question is, when the method showinfo runs, play is going all the way to the overwriten method and prints "[RM] IsraelyRockMusician Chanoch the king breaks his guitar!",
now this is fine, but the next line is "[M] Class name: Musician ", which means the getClassName was given "Musician" and Im asking why its not "IsraeliRockMusician" since the method was overwritten.
I'm sorry if the question is a bit hazey.
The problem is that the method of the base class has private access.
private String getClassName(){
return "Musician ";
}
Change it to public/protected so you can override it.
Instead of having a function where you hardcode the class name, you should use the following:
public class Foo {
public void printClassName() {
System.out.println(this.getClass().getName());
}
}
This way, if you change your class name, you don't need to update the method that you've written. One caveat to this is if you run an obfuscation tool against your code, the class name may be replaced with random characters. In that case, you can create a const string in your class and refer to that instead.

How to change the value of private variable in java

I started to programm in Java since Yesterday, and I have the biggest question of my entire programmer life(since Yesterday).
For example, let's say I have a code like this:
public class itsAClass {
static private String A;
public static void main() {
A = "This should be changed";
}
public String something() {
return A;
}
}
I wanted to use the method something() in another Class to get the String Sentence of A, but I got only null.
How can I change the value of A, so that the another Class can get the Value "This should be changed"?
If you just want to bring this code to work you just can make something() static as well.
But this will be not the right way to approach this problem.
If you want to hold code in the main class you could do something like this:
public class AClass {
private String a;
public static void main() {
AClass myC = new AClass();
myC.setA("This should be changed");
// than use myC for your further access
}
public String something() {
return a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
If you want to access it by a external class without direct reference you can checkout the singleton pattern.
public class AClass {
private final static AClass INSTANCE = new AClass();
private String a;
public static void main() {
getSingleton().setA("This should be changed");
}
public String something() {
return a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public static AClass getSingleton() {
return INSTANCE;
}
}
This way you can access it via AClass.getSingleton() from any location of your code.
You have to call your main() function.
In another class:
itsAClass aClassObj = new itsAClass();
aClassObj.main();
// or rather itsAClass.main() as it is a static function
// now A's value changed
System.out.println(aClassObj.something());
the way to set the value of private variable is by setter and getter methods in class.
example below
public class Test {
private String name;
private String idNum;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getIdNum() {
return idNum;
}
public void setAge( int newAge) {
age = newAge;
}
public void setName(String newName) {
name = newName;
}
public void setIdNum( String newId) {
idNum = newId;
}
}
you can call method main() in method something().
public class itsAClass{
static private String A;
public static void main() {
A = "This should be changed";
}
public String something() {
main();
return A;
}
public static void main(String[] args){
itsAClass a1 = new itsAClass();
System.out.println(a1.something());// prints This should be changed
}
}

Why do I get this weird output?

I have three classes
public abstract class Champion
{
private String name;
public Champion(String ChName)
{
name = ChName;
}
public void setName(String ChName)
{
name = ChName;
}
public String getName()
{
return name;
}
}
second:
public class Mage extends Champion {
public Mage(String ChName)
{
super(ChName);
}
public String toString()
{
return String.format("%s",super.toString());
}
}
and my main:
public class JavaApplication2 {
public static void main(String[] args) {
Mage mage = new Mage("ori");
System.out.println("champion is "+mage);
}
}
The output should be "champion is ori"
but I get:
"champion is javaapplication2.Mage#1fee6fc"
What am I doing wrong?
You need to override toString() in Champion as the call to super.toString() in Mage.toString() will be calling Object.toString().
By calling super.toString() you call the Object toString() method, giving you the result you see.
You need to implement the Champion toString() method.

Java: Class.this

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.

Categories

Resources