I'm having difficulty implementing an abstract class structure and was wondering if someone could tell me what i'm doing wrong.
I want to have an abstract parent class Num for which has abstract methods:
Code:
abstract Num add(Num n);
abstract Num multiply(Num n)
where we have two (for now) subclasses:
Code:
public class ComplexNum extends Num
public class RealNum extends Num
What I want to be able to do is to create a generic object for which the suitable method is used:
Code:
Num testNum = new ComplexNum(...)
Num otherTestNum = new RealNum(...)
testNum.multiply(otherTestNum) // doesn't care what type objs are, handled in subclass
The two ways that I have tried have failed, namely:
1. Explicitly defining the cases in the abstract class, fails as I want to be able to pass a general Num object i.e. use multiply(Num n), and have the correct method used in the child class.
Code:
abstract Num add(RealNum n);
abstract Num add(ComplexNum n);
etc
2. Use type checking in the subclass:
Code:
public Num add(Num n){
if(n instanceof ComplexNum){
...
}
}
Both seem very anti-OOP, and neither yet work either...
what's the difference in multiplying real's and complex's? real's are complex numbers with no i coordinates. i don't think inheritance is the proper way for you to code your classes.
(here's a simpler example: You have Lion and Tiger, which are child classes of Cat, but there are no attributes that are distinct to Lion or Tiger that would not already be in cat: Size, HasMane, Color, Primary Location, etc)
Sorry, I don't think I explained it particularly well. Basically I wanted to have a abstract object as parent class, with methods that took the object itself as an argument type. Then have the extended method in the child class catch all possible cases of subclasses. Basically i got round it by using instanceof and casting:
Code:
// subclass extending abstract method
public foo(ParentObject p){
if(p instanceof SubclassObj1){
SubclassObj1 test = (SubclassObj1) p;
// do useful things
}else if(... catch other cases){
// cast alternate cases
}else{
// throw exception or something
}
}
no, I understood you just fine. my point was that maybe you shouldn't be putting all of this into the Num class or any of its children. Maybe a class defined something like this would be more sensible.
Code:
public class SomeClass {
public static Num add(Num, Num);
public static Num add(Num, RealNum);
public static Num add(Num, ComplexNum);
}
My second point was that RealNum's are simplified versions of ComplexNums. Assuming that a complex number is a+bi; a real number is also a+bi where b = 0; So if complex nums was something like... (for arguments sake)
Code:
public class ComplexNum {
public ComplexNum(int a, int b);
}
A real number would be defined like...
Code:
public class RealNum extends ComplexNum {
public RealNum(int a) { super(a,0); }
}
So what it's really saying is that a real and a complex are essentially the same class, just for a real number, b's always 0.
and of course you need to figure out what happens in the following scenario,
Code:
ComplexNum c1 = new ComplexNum(4,3);
ComplexNum c2 = new ComplexNum(4,-3);
Num n1 = c1.add(c2);
Is n1 now a ComplexNum (since it came from the ComplexNum class) or a RealNum (since its b is 0)
Assuming of course your add implementation is something like...
Code:
//complex num
return new ComplexNum(this.a+other.a,this.b+other.b);
//real or complex
if(this.b + other.b == 0) {
return new RealNum(this.a+other.a);
} else {
return new ComplexNum(this.a+other.a,this.b+other.b);
}
Bookmarks