I have created 3 classes, one superclass "a" and under a two subclasses "b" and "c". I am creating an instance of c, give it an integer "n" and then use subclass b to do some calculation. The problem I am having is that when I create an instance c to call b, the data technically belong to the superclass a/c right? so when i create an instance of b with
b b_instance = new b();
inside the instance of c,
the b calc() function I call would return 0. I guess it's because b has it's own eco-sphere of data?
How do I do this?
2)
Also, how do i call the superclass function of the same name?
Thanks!
public class prog
{
public static void main(String args[])
{
c c1 = new c();
c1.run();
}
}
class a
{
private int number;
void set_number(int n)
{
number = n;
}
int get_number()
{
return number;
}
int calc()
{
return number*2;
}
}
class b extends a
{
int calc()
{
// calling the superclass function calc, then subtract
return super.calc() - get_number();
}
}
class c extends a
{
void run()
{
set_number(1);
b b1 = new b();
System.out.println(b1.calc());
}
}
infinite loop problem
public class prog
{
public static void main(String args[])
{
c c1 = new c();
c1.run();
}
}
class a
{
void calc_a()
{
System.out.println("") ;
}
void calc_b()
{
calc_a(); // meaning the calc_a() in the superclass
}
}
class b extends a
{
void calc_a()
{
super.calc_b();
}
}
class c extends a
{
void run()
{
b b1 = new b();
b1.calc_b();
}
}
b b_instance = new b();
inside the instance of c, the b calc() function I call would return 0.
I guess it's because b has it's own eco-sphere of data?
How do I do this?
A "couple" of possible ways. I'd consider extending c from b, this way c gets all the functionality of a and b, something like...
class c extends b {
void run() {
set_number(1);
System.out.println(calc());
}
}
IF, however, this is not feasible (for some reason or other), then you need to pass the value that c has to b, something like...
class c extends a {
void run() {
set_number(1);
b b1 = new b();
b1.set_number(get_number());
System.out.println(b1.calc());
}
}
Now, having said that, this "smells" to me. What's the point of extending from a just so c can perform b? It would set off alarm bells to me.
The problem is, if your call c#calc, it's just going to a's calc method ... which, based on run, doesn't seem to be what you want to achieve, so it's all just a big mess
2)
Also, how do i call the superclass function of the same name?
Because calling calc directly would cause a StackOverflowError because you're constantly calling yourself.
In this case, you're taking the operation that a is doing and making a modification to it. This is a common practice in OO languages.
Side notes...
Java (and the Java community) already have a well defined set of coding practices. You should take the time to learn them, it will make your code easier to read and make it easier for you to read other peoples codes.
Start with Code Conventions for the Java TM Programming Language
Class names should start with a capital letter and methods are in camelCase, for example...
class A {
private int number;
void setNumber(int n) {
number = n;
}
int getNumber() {
return number;
}
int calc() {
return number * 2;
}
}
Updated...
class a {
void calc_a() {
System.out.println("");
}
void calc_b() {
calc_a(); // meaning the calc_a() in the superclass
}
}
class b extends a {
void calc_a() {
super.calc_b();
}
}
class c extends a {
void run() {
b b1 = new b();
b1.calc_b();
}
}
The question you need to ask yourself is, why does b need to override calc_a? Why not override calc_b? It would solve the issue
how do i override it?
class b extends a {
//void calc_a() {
// super.calc_b();
//}
#Override
void calc_b() {
super.calc_b();
}
}
Related
This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}
I have following situation and would like to know the best way to design my solution
public abstract class A {
public abstract A getHelper();
public abstract void launchHandle();
public static A initHelper(String condition) throws Exception {
if ( condition == 'xyz') {
return C.getHelper();
} else {
return B.getHelper();
}
}
}
public class B extends A {
protected static A b;
#Override
public A getHelper() {
b = new B();
return b;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle");
}
public String getName() {
return "I am from Class B";
}
}
public class C extends A {
protected static A c;
#Override
public A getHelper() {
c = new C();
return c;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle from C");
}
public String getValue() {
return "I am from Class C";
}
}
**Executor class**
public class Executor {
public static void main(String[] args) {
A aa = a.initHelper(condition);
}
}
Now in the above approach, i am unable to access methods like aa.getName() from Class B OR aa.getValue() from Class C, which makes sense. However how to get these methods in executor class? Executor does not know anything about Class B & C and should not know. Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
Please help design this and what could be best way to solve this.
Thanks in advance.
Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
If you take a closer look at your code, you will notice that the only contract constant across all your classes is the launchHandle method (baring getHelper and initHelper which are simply used for instantiating the right subclass). There is no real relation between B and C other than the fact that their instantiation is controlled by A.
This is how I would consider approaching the problem :
Executor Factory
Make Executor an abstract class rather than making it the entry point of your program :
public abstract class Executor {
public abstract void performTask();
public static void execute(String condition) {
Executor executor = null;
if ( condition.equals("xyz")) {
executor = new AExector();
} else {
executor = new BExecutor();
}
executor.performTask();
}
}
Executor implementations
Create a different implementation for operating on B called BExecutor :
public class BExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from B");
//create or get data to perform the task on
B b = new B();
String name = b.getName();
System.out.println("I am from "+name);
}
}
Create a different implementation for operating on C called CExecutor :
public class CExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from C");
//create or get data to perform the task on
C c = new C();
String value = c.getValue();
System.out.println("I am from "+value);
}
}
Your main method can then look like this :
public static void main(String []args) {
Executor executor = Executor.execute(condition);
}
And for some reason, if you do find some common contract between B and C, you an always create an interface which both B and C can implement and use a reference of this interface instead of using a B or C reference.
Add getName and getValue to A as abstract methods.
I'm confused with method references. Consider the following script.
public class Main {
static interface I {
void m();
}
static class A implements I {
#Override
public void m() {
System.out.println("A");
}
}
static class B implements I {
#Override
public void m() {
System.out.println("B");
}
}
public static void main(String[] args) {
A a = new A(); B b = new B();
I i; Runnable r;
i = a;
r = i::m; // static reference? might infere class
r.run(); // prints "A"
run(i); // also prints "A"
i = b;
r.run(); // prints "A" instead of "B"!
run(i); // prints "B"
r = i::m;
r.run(); // now prints "B"
run(i); // also prints "B"
}
public static void run(I i) {
Runnable r = i::m; // dynamic reference, cannot infere class
r.run();
}
}
So it seems that:
The compiler cannot inline method references because they are polymorphic. They are not resolved at compilation time, but at runtime.
But i::m does not behave like i.m()...
So my questions are:
Are method references using reflection? And why they do only once?
If you think about how this code would be written without method references, but with classes and objects, it all makes sense:
r = i::m;
is basically equivalent to
private class IRunnable implements Runnable {
private I i;
public IRunnable(I i) {
this.i = i;
}
#Override
public void run() {
i.m();
}
}
Runnable r = new IRunnable(i);
So, if you assign another value to i after the IRunnable has been constructed, the IRunnable continues referencing the previous value, and calling its run() method again will still call the previous i's method.
Why does below code prints "1" ?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println("Base");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println("CovariantReturn");
return new B();
}
/**
* #param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
Because you are referring to fields, which are not affected by polymorphism. If you instead used getX(), it would've returned 2.
What you are asking is, the value of field x defined in class A (because Base.getObject() returns A). Even though CovariantReturn overrides the method to return B, you are not referring to your object as CovariantReturn.
To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A and so A.x is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A but return an instance of B, the method you invoke will be invoked on B.
#kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.
As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.
class Base {
int i = 1;
void method() {
System.out.println("in base");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println("in sub");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
This code will print - in sub and 1
Im newbie in Java and im learning it.
Right now i have two class, i already called class B on class A constructor
class A
public A {
init();
B bb = new B(textField);
bb.doSomething();
}
void init() {
textField = new JTextField();
}
void fly() {
//can i just use bb.doFly();
}
private JTextField textField;
}
My question is, do i have to initialized B bb = new B(); on every single function i want to use on A ?
Question Edited
Its all about scope. If your attribute is at class level, then no you do not have to create a new one each time.
If the attribute is only created within a method scope, then yes you do.
The difference is
class A {
public A() {
// this is at method level scope. It is define INSIDE a method
B bb = new B();
}
}
class level scope is
class A {
// this is at class level scope. It is define OUTSIDE a method
B bb = new B();
public A() {
}
}
No, just refer to the identifier bb:
public class A {
private B bb = new B;
public A() {
}
public void foo() {
bb.printHello(); // you can only call methods on bb which class B supplies
bb.fly(); // won't work; you can only call fly() on objects of type A
}
public void bar() {
bb.printWorld();
}
public void fly() {
System.out.println("I'm flying...");
}
}
public class B {
public B() {
}
public printHello() {
System.out.println("Hello");
}
public printWorld() {
System.out.println("Hello");
}
}
Just a note: Please declare all your attributes private unless you have a good reason to not to.
class A
B bb;
public A {
bb = new B();
bb.doSomething();
}
void fly() {
bb.something()
}
}
No. Suppose you have this code this code:
public class NameOfProgram
{
public static void main(String[] args)
{
A aa = new A();
aa.fly();
}
}
Then the variable bb inside aa is created with the statement new A(). So, you don't have to create an B object and set it to bb as it already exists.
Also, you need to declare the variable outside the constructor or you will not be able to use it in other methods, like fly. To correct it you could do this:
public class A
{
B bb; <-----------------
public A()
{
bb = new B(NameOfVariableIForgotAbout);
}
public void fly()
{
bb.doFly() //Now this should work
}
}
you can also but the B bb; after the method, I just prefer it this way.
Also, your class A has a few errors (so you note for future reference). Firstly, if you want to be able to call a method from an instance of the class (A aa = new A(); aa.fly()) then you need to make the methods public like so:
public void fly()
{
//Insert code here
}
Also , you declared the constructor wrongly. Here is how you did it:
public A
{
//Insert code here
}
and it is done like this:
public A()
{
//Insert code here
}
The first error will cause a compile-time error if you make the call aa.fly() because it is neither private nor public.
The second will cause a compile-time error even if you make no call to the method.