public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
I want to use A's foo, what is the syntax for doing that? I tried a.super.foo();.
Thank you
You can only do so from within the class B. You won't be able to invoke A's foo from outside A or B classes.
A a= new B(); will always set the reference a to an instance of B. Thus, even though you cast it to A, at runtime the method that gets invoked is B.foo. That's runtime polymorphism.
I am really uneasy about a design that needs to do this kind of thing. If you want the object to behave like an A, why did you create a B?
You cannot use super from the outside of the class. Assuming you really, really need this (but I really doubt you can't find a better way) the best you can do about it is to expose a method that does this call to the outside:
public class B extends A {
public void super_foo() {
super.foo();
}
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.super_foo();
}
}
Here is it
public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
super.foo();
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
You can't access it. The keyword is that it has been overridden by Java so it's no longer accessible.
What you want to achieve will work if the method is static. Non virtual methods in java
public class A {
public static void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public static void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
Related
I want to ask a question about java constructor.
Example,i have "A" class and "B" class and i created constructor in "b" class. In normal way, when i create "b" class object in main method of "a" class, class "b" constructor will automatically work. So, my question is when I create b class object in "a" class,i want to work other functions first before working constructor.
So what should i do?
public class A {
public static void main(String[] args) {
B b = new B();
}
}
public class B {
public B() {
System.out.print("Hello Constructor");
}
public void m() {
System.out.print("Hello Method");
}
}
Normally :: Output :: Hello Constructor
Hello Method
i want this Output :: Hello Method Hello Constructor
Can be? Sorry for my bad English...
Inside the constructor of B, call the method M. your question is a tad confusing, but if I understand you correctly, this is what you want.
public class A{
public static void main(String[] args){
B bb=new B();
}
public class B{
public B(){
M();
System.out.print("Hello Constructor");
}
public void M(){
System.out.print("Hello Method");
}
actually you can't do it with your thinking way(or i don't know a way for it) but you can try this:
public class A {
public static void main(String[] args) {
B b = new B();
}
}
public class B {
public B() {
//write what are you wanting to do like m(); for this exapmle
System.out.print("Hello Constructor");
}
public void m() {
System.out.print("Hello Method");
}
}
its simple trick but it wokrs.By the way you can try it without constructor like initializing your variables with another method:
public class A{
public static void main(String[] args){
B bb=new B();
bb.m();
bb.b();
}
public class B{
public void b(){
System.out.print("Hello Constructor");
}
public void m(){
System.out.print("Hello Method");
}
Let's say I have three Classes A,B,C.
All three do the same thing, but in a different way, they differ in efficiency.
All the method names, variable names inside the three classes are same.
class A{
public static int method(){
......
return result;
}
}
class B{
public static method(){
......
return result;
}
}
class C{
public static method(){
......
return result;
}
}
I have test class, which has a method to test the code in the above three classes. Since this testMethod() is common to all the three classes, is there a way to call this method with objects of classes A,B,C ?
class Test{
public static int testMethod(Object ABC)
{
return ABC.method();
}
public static void main(String[] args){
A a = new A();
SOP(testMethod(a));
B b = new B();
SOP(testMethod(b));
C c = new C();
SOP(testMethod(c));
}
}
The only approach I can think of is creating three different methods for each of the classes, like this.
class Test{
public static int testMethodA(A a)
{
return a.method();
}
public static int testMethodB(B b)
{
return b.method();
}
public static int testMethodC(C c)
{
return c.method();
}
public main()
{
//call to each of the three methods
............
}
What is the best approach to this scenario? Basically I want to have only one method that can test all three classes.
Create an interface with the common method for all classes. Then, make each class implement this interface. In your test code, use the interface as parameter type and pass an instance of each class to the method. Note that when you do this, the method to test should not be static.
In code:
public interface MyInterface {
//automatically public
int method();
}
public class A implements MyInterface {
#Override //important
//not static
public int method() {
/* your implementation goes here*/
return ...;
}
}
public class B implements MyInterface {
#Override //important to check method override at compile time
public int method() {
/* your implementation goes here*/
return ...;
}
}
//define any other class...
Then the test:
public class Test {
//using plain naive console app
public static void main(String[] args) {
MyInterface myInterfaceA = new A();
testMethod(myInterfaceA);
MyInterface myInterfaceB = new B();
testMethod(myInterfaceB);
//and more...
}
public static void testMethod(MyInterface myInterface) {
myInterface.method();
}
}
Or if you prefer to use JUnit:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class MyInterfaceTest {
MyInterface myInterface;
#Test
public void methodUsingAImplementation() {
myInterface = new A();
//code more human-readable and easier to check where the code fails
assertThat(myInterface.method(), equalTo(<expectedValue>));
}
//similar test cases for other implementations
}
Consider this example (warning-very bad code):
public abstract class A {
static float foo;
public static void loadfoo(float incomingfoo) {
foo = incomingfoo;
}
public static void displayfoo() {
System.out.println("your foo is" +foo);
}
}
Class B extends Class A
public class B extends A {
static float foo;
//#Override (overide is not allowed for static methods. dis is a problem...)
public static void loadfoo(float incomingfoo){
foo = incomingfoo;
}
}
Class C is pretty much the same as B
public class C extends A {
static float foo;
//#Override
public static void loadfoo(float incomingfoo) {
//I would like a different static variable loaded into this class using this method
foo = incomingfoo;
}
}
finally the main Class runs the thing
public class Main {
public static void main(String whatever[]){
B.loadfoo(5);
C.loadfoo(8);
B.displayfoo();
C.displayfoo();
}
}
so the output of this is :
your foo is0.0
your foo is0.0
and I am aware this is because the displayfoo class reference the static foo in Class A, so please disregard this. I assume I have now been specific enough about describing my problem and goal. solutions anyone?
Edit: I feel like an idiot I completely forgot to actually state what I wanted to accomplish, but really all I want is for B and C to have there own static variables loaded into them without altering A's variable, which should be the default.
It looks like you need static access to two stateful objects with the same structure. In this case, an enum might be a solution:
public enum A {
B, C;
private float foo;
// getter and (optional) setter for foo here
public void displayFoo() { System.out.println("This foo is " + foo); }
}
This way you can still access your object statically, but don't need to duplicate anything else:
A.B.setFoo(5);
A.C.setFoo(8);
A.B.displayFoo(); // 5
A.C.displayFoo(); // 8
If you then need a static default, I would make it a method on A:
enum A {
A getDefault() { return A.B; }
}
A.getDefault().displayFoo();
It seems that first you want to load the values using loadfoo to foo and then display the value of that foo using the displayfoo method. Well, I don't think there is anyway to do it using static methods.You can do this by making displayfoo() method abstract and overriding the same in the subclasses B and C.
Here is the code:
abstract class A {
float foo;
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
public abstract void displayfoo();
}
class B extends A{
#Override
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
class C extends A{
#Override
public void loadfoo(float incomingfoo){
this.foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
public class Main {
public static void main(String whatever[]){
B b = new B();
C c = new C();
b.loadfoo(5);
c.loadfoo(5);
b.displayfoo();
c.displayfoo();
}
}
You can also check the same kind of question here.
Static methods should be used by static method access and not by object instance. It's not supposed to be virtual because it's not belong to the object.
If you call B.loadfoo() then a method of B class is called.
If you call C.loadfoo() then a method of C class is called.
You cannot call a static method if it doesn't exist in the class.
There's no point to use static methods if you want to use polimorphism.
In the code below, myString is always initialized to null. I have to manually initialize in an init() or similar. As far as I can tell it is related to superclass/subclass but I don't understand the exact mechanism
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
c();
}
public void c() {
}
}
The issue with your code is, that myString is initialized at the begin of the constructor of class A but right after the super constructor (i.e. class B). Since you access the variable before from the constructor of class B (indirectly via call to overriden methode c) your get this behaviour.
As a rule of thumb: if you want to avoid unexpected behavior do not call overriden methods before the constructor has been executed.
Add a call to c(); overidden method right after the object has been fully created and call to superclass constructor is done.
Change your code to this ..
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
c(); // Include the call to c(); here ...
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
}
public void c() {
}
}
// Output : test
Thinking in Java Second Edition by Bruce Eckel, Behavior of polymorphic methods
inside constructors (p. 337-339).
i have this example:
class One
{
public void testOne(){System.out.println("One!!!");}
public void testTwo(){System.out.println("One!!!");}
}
public class Jenia extends One
{
static void test(One o) {o.testOne(); o.testTwo();}
public static void main(String args[])
{
test(new One());
}
}
Results:
One!!!
One!!!
ok, no questions.
than, i try modified my code:
only this method:
public static void main(String args[])
{
test(new Jenia());
}
results:
One!!!
One!!!
ok, we have this results because - here upcasting(Jenia-One).
its all ok too, but, modified again:
in class Jenia override methodtestOne`:
public void testOne(){System.out.println("Two!!!");}
so i have this code:
class One
{
public void testOne(){System.out.println("One!!!");}
public void testTwo(){System.out.println("One!!!");}
}
public class Jenia extends One
{
public void testOne(){System.out.println("Two!!!");}
static void test(One o){o.testOne(); o.testTwo();}
public static void main(String args[])
{
test(new Jenia());
}
}
and results:
Two!!!
One!!!
my question: why Two!!! ?? why we not lost override methods?
Because all the methods in Java are virtual in terms of C++/C# and all the values passed by reference. So when you call some method, the type of the reference is irrelevant, what is important is the type of the object it points to. In your case the object is of Jenia type, so Jenia method gets called.
Thats the desired behaviour.. which method gets called depends on the runtime type, not the reference type. Since the obect is type of Jenia, the Jenia version of testOne gets called, even if the reference is type of One. Thats plain old polymorphism.
See the explanation in comments
class One
{
public void testOne(){System.out.println("One!!!");}//method one
public void testTwo(){System.out.println("One!!!");}//method two
}
public class Jenia extends One
{
public void testOne(){System.out.println("Two!!!");}//method 3
static void test(One o){o.testOne(); o.testTwo();}//method 4
public static void main(String args[])
{
test(new Jenia());//calls method 4 which in turns calls 3 and 2.
}
}
}
When you call o.testOne() in test method, it calls Jenia.testOne since the o is an instance of Jenia. You can check it by o.getClass().getName();.
java overriding here is the tutorial http://download.oracle.com/javase/tutorial/java/IandI/override.html
public class A {
void print() {
System.out.println("A");
}
public static void main(String[] args){
A a1 = new A();
a1.print(); // A
A a2 = new B();
a2.print(); // B ! because it overrides print method
B b = new B();
b.print(); // B
}
}
class B extends A {
void print() {
System.out.println("B");
}
}