polymorphic call depends on variable - java

I have the following problem. Am trying to make a polymorphic call and the result would depend on the variable that changes value depending on the underlying class. Tried different things however it doesn't work. Please let me know what should be changed. Problem is that although c.w reads both the local variable w, which is defaulted to 0 and reads the one from appropriate class it always defaults to 0. Here is the code:
class Cycle{
private int w = 0;
public void move(){
System.out.println("Cycle moving");
}
public int wheels(Cycle c){
switch (c.w){
case 1: return 1;
case 2: return 2;
case 3: return 3;
default: return 0;
}
}
}
class Unicycle extends Cycle{
public int w = 1;
public void go(){
System.out.println("Unicycle go");
}
}
class Bicycle extends Cycle{
public int w = 2;
public void go(){
System.out.println("Bicycle go");
}
}
class Tricycle extends Cycle{
public int w = 3;
public void go(){
System.out.println("Tricycle go");
}
}
public class TestCycle {
public static void ride(Cycle c){
c.move();
int now = c.wheels(c);
System.out.println(now);
}
public static void main(String[] args){
Bicycle b = new Bicycle();
ride(b);
Unicycle u = new Unicycle();
ride(u);
Tricycle t = new Tricycle();
ride(t);
}
}

Your problem (well one of them) is that you are redefining the class variable 'w' in each of your subclasses. Define it one as a member of 'Cycle' and have each subclass set it correctly in their constructors.
class Cycle{
protected int w;
public void move(){
System.out.println("Cycle moving");
}
public int wheels(){
return w;
}
}
class Unicycle extends Cycle{
public Unicycle() {
w = 1;
}
public void go(){
System.out.println("Unicycle go");
}
}
Or you can define an abstract method called 'wheels()' in the superclass and override it in the subclasses. It's a matter of taste.

the wheels method should be more like
public int getWheelCount(){
return this.w;
}
You invoke it on the instance itself, you don't need to pass an argument. If the current instance is a Tricycle, the method will return 3, etc...

Since Cycle.w is private, it's not visible from its inheritors. This means that for example Tricycle.w it's not the "same" variable, and it's not visible in Cycle (that's why you always get 0). You have to make Cycle.w at least protected, then remove w from all subclasses, and set its value in each subclass's constructor to what you want.

It's probably not the answer you are looking for, but the following works. Please give more details on what you are trying to do.
public abstract class Cycle {
protected int nWheels;
protected String goText;
// no constructor.
public void go() {
System.out.println(goText);
}
public int wheels() {
return nWheels;
}
}
...
public class Unicycle extends Cycle {
public Unicycle() {
nWheels = 1;
goText = "Unicycle go";
}
}
Note that I made Cycle abstract because I don't want it to ever be instantiated.
EDIT:
public static int getNumberOfWheels(Cycle cycle) {
return cycle.wheels();
}
which is obviously not very useful since a simple call to cycle.wheels() would do the same as calling this function.
I'm not sure why you want to avoid constructors. Maybe you should write the exact question you are trying to answer.

Related

Java how to make a method argument accept subclass type and superclass

I have a superclass and one subclass with some variables like below:
public class A{
private int first;
private int second;
public A(int _first, int _second){
first = _first;
second = _second;
}
public int getFirst(){
return first;
}
}
public class B extends A{
private int third;
public B(int _first, int _second, int _third){
super(_first, _second);
third = _third;
}
public int getThird(){
return third;
}
}
I want to build a method in the main class that accepts a generic argument that can be of type A or type B like below:
public class Main{
public int val = 2;
public static void main(String []args){
A a = new A(1, 2);
B b = new B(1, 2, 3);
printObject(a);
printObject(b);
}
public void printObject(A a){
int f = a.getFirst() * val;
int s = a.getSecond() * val;
if(a instanceOf B){
int t = a.getThird() * val; // compiler does not find the getThird() method this way
}
}
}
How can this be achieved?. is generics an option? I have thought about making printObject() method inside A then override it inside B however I have some other variable like val above that I am creating in main.
update
I tried to use instanceOf like the above method. But this way the compiler does not find the subclass's specific method.
Firstly, by definition, if you declare A as a parameter to any method and B is it's sub-class, then any A or B can be passed to that method.
You could then achieve what you want using the instanceof operator (to check if the parameter passed in is of type B). However, inheritance / method override should typically be used rather than instanceof.
You could pass 'val' into the printObject() methods on A/B. If several variables like 'val' are involved you could pass in another object or perhaps you need to split your code across multiple methods on class A (overridden in B), passing in different values as appropriate? (You wouldn't normally do calculations in a method whose purpose is to print an object but perhaps that was just an example?)
Everything is much simplier) You could get rid of this method in the main class, cause it's producing some redundant coupling. And all this instanceof really smells in 2019. You could make it more independent.
Class A:
public class A{
private int first;
private int second;
public A(int _first, int _second){
first = _first;
second = _second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public void print(int multiplier) {
System.out.println(this.first * multiplier);
System.out.println(this.second * multiplier);
}
}
Class B:
public class B{
private int third;
public B(int _first, int _second, int _third){
super(_first, _second);
third = _third;
}
public int getThird(){
return this.third;
}
#Override
public void print(int multiplier) {
super.print(multiplier);
System.out.println(this.third * multiplier);
}
}
Class Main:
public class Main{
public int val = 2;
public static void main(String []args){
A a = new A(1, 2);
B b = new B(1, 2, 3);
a.print(val);
b.print(val);
}
}
Writing object oriented code is more than extending a class , your API's and other functionality should be designed as part of the solution.
In your case, the most appropriate way to do this is to add the print method to the object itself, you can either override the entire function or to call the super class inside the overriding class.
public class A{
/// ... your code
public void print(){
System.out.println("first :"+first+", second : "+second);
}
}
public class B extends A{
/// ... your code
public void print(){
//Option A - use parent class getters/setters to implement print for object B
System.out.println("first :"+super.getFirst()+", second : "+super.getsecond() +" third" + third);
}
//Option B (More usable to methods returning a value or performing an update) - Perform operation on parent variables, then perform on class specific variables
super.print()
System.out.println("third : "+third);
}
}
and then
A a = new A();
A b = new B();
a.print();
b.print();
Will each call the correct runtime function based on their actual implementation

In Java how to refer subclass variable without declaring that variable in parent class?

public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.

Adding specific values for inherited fields

I am having some trouble with inheritance (Student here). I need to be able to utilize 1 inherited private field for each subclass I make. Obviously subclasses cannot have access to inherited fields however when a new object is created that inherited private field is a part of that object. For my purposes though each subclass needs to have it's own specific value for that inherited field. My first attempt looks something like this:
Public class A {
private int x = 0;
public A(int n) {
x = n;
}
public int useX() {
return x;
}
}
Public class B Extends A {
int n = 1;
public B() {
super(n);
}
useX(); // Return 1?
}
Public class C Extends A {
int n = 2;
public B() {
super(n);
}
useX(); // Return 2?
}
However my professors tell me that I could also be using a setter method inside of my Super class to create that new field, and from there I am confused. Can anyone help point me in the right direction?
An ordinary Java Bean provides public accessors and mutators (aka getters and setters) for it's fields. However, you could provide a protected setter. Something like,
public class A {
private int x = 0;
public int getX() { // <-- the usual name.
return x;
}
protected void setX(int x) {
this.x = x;
}
}
Then your subclasses can invoke that setter
public class B extends A {
public B() {
super();
setX(1);
}
}
And then B.getX() (or B.useX() if you really prefer) will return 1.

Access methods based on constructor provided

In my program, I want to be able to access certain methods based on the constructor I initialize and nothing else. For example:
public class A {
int paramOne;
float paramTwo;
public A(int paramOne) {
// Constructor One
}
public A(float paramTwo) {
// Constructor Two
}
public void ConstructorOneMethodOnly(int paramOne) {
// Only used when Constructor One is initialized
}
public void ConstructorTwoMethodOnly(float paramTwo) {
// Only used when Constructor Two is initialized
}
}
In the code given, is there a way of achieving what I have described in the comments and in my question? If so, can you describe how to do so?
As per Sotirios Delimanolis' comment, you can not restrict the accessibility of a method based on the constructor used.
I think this logic should be divided into two class, that is the more clear implementation I can find out.
public class IntDemo {
int paramOne;
public IntDemo (int paramOne) {
...
}
public void ConstructorOneMethodOnly(int paramOne) {
...
}
}
class FloatDemo {
float paramTwo;
public FloatDemo(float paramTwo) {
...
}
public void ConstructorTwoMethodOnly(float paramTwo) {
...
}
}
public class A {
int paramOne;
float paramTwo;
int constr = 0;
public A(int paramOne) {
// Constructor One
constr = 1;
}
public A(float paramTwo) {
// Constructor Two
constr = 2;
}
}
and check constr variable before invoking methods.
Im not sure if this directly helps you but it may help you and more.
I suggest using a generic class like this.
public class A<T> {
public A(final T t) {
}
public void method(final T t) {
}
}
If you dont know how to use a generic class here is an exmaple
final A<Integer> aInteger = new A<Integer>(1);
final A<Float> aFloat = new A<Float>(5.4f);
Hope this helped!

Inheritance in Java

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());
}
}

Categories

Resources