Same getters and setters in 2 child classes..? - java

I'm not that good OO design .. so please bear with me..
I have Class A, And 2 classes which extend A. But both of them have same fields.. So what is better, to have getter / setters in A or to have same getter / setters in both child classes.. Or is there a better a way to do this..?
this is what i have done (mock)..
class A{
private int x;
protected A(int x){
this.x = x;
}
public static A createA(id a, int x){
switch(a){
case 0:
return new C(x);
break;
//so on
}
public int getX(){
return x;
}
}
Thanks..

This depends on the classes
If those properties are a property of A then yes,
if it's just chance they have the same properties then no.
Basicly the question you need to ask yourself is, will there ever be a class that extends A that doesn't need those properties.
If the answer is no, put them on A,
If the answer is yes, keep them on the sub-classes,
or create another abstract class in between those 2 subclasses, having these 2 properties.

Let's say your classes are A (the parent) and B and C (the children). You say that B and C have some fields that are the same.
Ask yourself: If you had another class D, child of A, would it have those fields too regardless of its specific functionality?
If the answer is yes, then the existence of these fields in both subclasses is definitely not a coincidence, so you should probably define them in A, because it means that they have these members precisely because they inherit from A.
If the answer is no, the existence of these fields in the subclasses may or may not be a coincidence. So, you should ask yourself: Even if D doesn't have these fields, does their existence in both B and C look more than just a coincidence? Do these classes share something that D, another child of A, simply doesn't happen to share?
If yes, then consider a new class E that extends A, with E defining these common members and then make B and C children of E instead of A.
If not (if it looks to you like just a coincidence), then leave your structure as it is. Or consider an interface instead.

Related

How to design when there is only one subclass need to be specified using polymorphism?

Given a base class Base, that's say A, B, C extends Base.
If there is a specific method m() only in C. To call m() , you should first determine if the given class is type of C , one of the way is to use:
otherMethod(Base b){
if(b instanceof C)
b.m();
}
But I'd like to use:
otherMethod(Base b){
b.m();
}
This means I have to pull the m() method up to the super class Base and only implement it in class C. But m() has no relation for class A and B and should not belong to them. This is not intuitive for code readability. So is there a better design of this case to use polymorphism and without non-reasonable method position?
If a class C has any specific method, same should not be part of Base class. To call the method m(), you will have to check the type of instance using instanceof operator and then cast your Base class to C and then call method m() like below
otherMethod(Base base){
If(base instanceof C){
C c= (C) base;
c.m();
}
}
Further, as others have already cited out the example of Collection and List, if your class C needs to have specific method, you should create one interface, lets say its called Child which should extend the Base interface. The other 2 classes should implement Base interface. And class C should implement Child interface.
Now, when you are designing Base interface, definitely, you won't know what specific methods other classes could implement. Therefore, you should not be calling any specific method in your otherMethod as well.
If you have Java 8 and performance is not an issue (which would be the case if you want to render 10000 shapes at 60fps) then filter the collection.
Assuming a Collection<Shape> shapes:
shapes.stream()
.filter(s -> s instanceof C)
.forEach(c -> ((C)c).m());
nb. You should never declare behavior (i.e. methods) in classes or interfaces that have nothing to do with it. In ernest_k's example, don't put get(int) in interface Collection just because List uses it. This keeps the class structure clean and understandable. Instead change the usage of the class structure, either the hard way (with type checking and casting) or by separating different subclasses in different collections (so you don't have to check types).
If you had this:
Collection<A> justA;
Collection<B> justB;
Collection<C> justC;
then you wouldn't have this problem, but then you would have another (probably worse) problem, that every time you add another subclass (say D) you have to change code all over the place, and there is the risk you forget to change it somewhere.
Don't infect the design further than adding a Base.visit(IVisitor v) {v.visit(this);}
interface IVisitor {
void visit(Base b);
}
Then write the IVisitor you need (here with the instanceof C)
Of course, you could just use Consumer instead of your own visitor interface. I just meant to be clear.
Another option is to use overriding methods. When calling otherMethod() on a Base object, it will call the doThings() defined in Base unless it is an instance of C, which has overloaded the doThings().
public class Base {
public void doThings() {
// nothing happens
}
public void otherMethod() {
doThings(); // will call method above if instance is Base object, will call method below if C object
}
}
class C extends Base {
public void doThings() {
System.out.println( "Things actually get done" );
}
}

In case of inner and outer classes, Java

There was one MCQ ( Multiple Choice Question ) while I was reading my Java study book and that MCQ is:
Question : In case of inner and outer classes, _________
Options are :
(a) The members of outer class can not be accessed by inner class.
(b) The members of inner class can not be accessed by outer class.
(c) Members of both can be accessed by both of the classes.
(d) None of these.
The answer given on book answer key is (b) but I'm not feeling it as right answer because outer class can access members of its inner class I think. So please help me with what is right.
Thanks, have a good day :)
lets make it simple with some code
public class A {
public int a = 1;
public class B {
public int b = 2;
public int getAfromB() { return a; } // ACCESS OUTER CLASS MEMBER IMPLICITLY
public int getBfromB() { return b; }
}
public int getBfromA() {
B myB1 = new B();
B myB2 = new B();
return myB1.b + myB2.b;
}
}
An B instance is linked to a specific A instance, it belongs to the instance scope. In its scope, the members of the A class are defined.
The A class can handle several instances of the B class. It will be able to manipulate them but cannot implicitly access a specific instance members, simply because 'b' is not unique from its perspective.
Sorry for the confusion.
You can access inner and outer classes both ways. I do suggest trying a simple example though yourself as programming is one of those things you only learn through your own problems.
Refer to this as this may help: Can an outer class access the members of inner class?

Going from Java to C++: how to use one custom class var within another custom class?

Let's say I have two custom classes in Java, class A and class B:
class A {
int x;
int y;
public A(int x, int y)
{
this.x = x;
this.y = y;
}
}
class B {
A a;
int z;
public B(A a, int z)
{
this.a = a;
this.z = z;
}
}
And I want to translate this situation into C++.
class A will translate more or less as it is, but when I go to class B and write such code:
class B {
A a;
int z;
public:
B(A a1, int z1){
a = a1;
z =z1;
}
};
it complains saying that class A does not have default constructor, so when I declare
A a;
at the top of class B it cannot instantiate my "a" variable (Java does not instantiate at declaration, whereas C++ does, as I understand).
So what would be the normal C++ way to deal with this situation: should I add default constructor without arguments to class A, or this is not the right way to go?
Thanks a lot.
Translating from Java to C++ is very sensitive to context. They are really very different languages and it depends heavily on what you are trying to achieve.
In Java user defined types are all accessed via references. The functional equivalent in C++ is a pointer. However in C++ you can access objects directly like built in types. So you could write this:
class A {
int x;
int y;
public:
// note: we don't initialize members in the body
A(int x, int y): x(x), y(y) {}
};
class B {
A a;
int z;
public:
B(A a, int z): a(a), z(z) {}
};
C++ gives you many more options how to refer to your user defined types and so it really depends on the larger problem you need to solve.
Some other possibilities:
std::shared_ptr<A> a; // much more Java-like (slower)
std::unique_ptr<A> a; // when you need one copy only (more common)
A* a; // when you need to live dangerously
A a; // use it more like a built-in
References:
std::unique_ptr when you only need to manage one
std::shared_ptr when the object needs to be managed from multiple places
NOTE: The difference between how you use Java and how you use C++ are so large that I would recommend forgetting about Java while you are dealing with C++. Learn C++ independently as a new language without constantly referring to the "Java way" of doing things.
Recommended books: The Definitive C++ Book Guide and List
in class B initialise instance of class A in initialisation list like so B(A a1, int z1):a(a1) {...}
This is required as instance of class A inside class B will be initialised before executing constructor body with default constructor, You have defined Your own constructor for A so there is no default constructor anymore. You can also initialise z1 variable the same way, like this:
B(A a1, int z1):a(a1),z(z1){...}
In Java, a declaration like:
A a;
means that you want a reference that can point to an object of type A. You eventually set it with something like:
a = new A(x, y, z);
In C++ the nearest simple thing is a pointer:
A* a;
When you write:
A a;
in C++, you are asking the compiler to make a local object, right here. So you have to supply all the constructor args. That's not what your Java code is doing, so you don't want it in C++ if what you are doing is a line-by-line, straight, port. (Hint: you would be better off writing yourself an explanation of what the program does and then creating a Java implementation in idiomatic Java from scratch.)
If you are trying to map from Java to C++, which is a very dangerous process, every declaration like:
A a;
has to map to either:
A* a;
or
A& a ... /* some initialization, unless a parameter or member. */
and you have to worry about all the storage allocation for yourself.
a = a1; is not an initialization of a. It's an assignment. a was already initialized before that statement (or would've been if it had a default constructor, hence the error).
In C++, each member variable is initialized before entering the constructor body. You have to use the member initialization list if you want to initialize a with a1:
B(A a1, int z1) : a(a1), z(z1) { /* constructor body */ }
This will simply initialize a with a1 and z with z1, and is the way to do it in C++.

Polymorphism: Least cumbersome way to assign data fields?

I'm currently taking a Java course and have a question about polymorphism.
Given
public class A {
private int a1;
public A(){}
public A(int a1) { this.a1 = a1;}
}
class B extends A {
private int b1;
public B() {}
public B(int b1, int a1) {
super(a1);
this.b1 = b1;
}
}
class C extends B {
private int c1;
public C(){}
public C(int c1, int b1, int a1) {
super(b1, a1);
this.c1 = c1;
}
}
What would be the best way to assign to fields a1, b1, and c1, all in one swoop? My first guess would be to make an instance of C and call its three-arg constructor.
But what happens when each class contains 10s or 100s of data fields? Wouldn't this approach mean calling constructors with huge numbers of arguments, like
C(arg1, arg2, ..., arg100), setting k of C's fields, then making a call to
B(arg1, arg2, ..., arg100-k), and so on,
all the way up to the top? Is there a better way to proceed?
Having so many parameters is a definite code smell; in all probability you want to split the object up into smaller self-contained objects and/or or collections.
On the other hand, there is the Builder pattern, where you use a helper class to set all the parameters and it constructs the object for you, possibly sanity-checking that all required fields are set and there are no conflicts.
Not in this particular case because the fields in the parent classes are declared private.
If they were protected then you could set all 3 of them from the class C constructor. However this breaks encapsulation because if the constructor for B did something else after the value was assigned you'd have to duplicate that logic in C in order to not violate it's contract, and as you can imagine that gets very messy when you have more constructors or parent classes in the type tree.
Having multiple calls chained in the manner you proposed is the safest way at the cost of having to call all those constructors up the chain. I'd recommend profiling your code to see if this is actually a problem and not just a premature optimization.
What you're suggesting would work if you set the class fields to public. Class C will have a1 and c1, but won't be able to access them due to them being private.

object ref in Java programming

I want to know about the advantage in between the creating an object for sub class but assigning class A ref instead of assigning Class B ref. which is shown in line1,line2 below code
class A
{
int b=10;
}
class B extends A
{
int b=12;
}
class Test
{
public static void main(String[] args)
{
A a=new B(); //line1
//B a=new B();//line2
System.our.println(a.b);
}
}
If you're not going to need any methods specific to B, in other words, you're strictly going to use it as an A, it's an advantage for readability to state so.
But the main advantage comes to light when you use the general type in a method declaration:
public String resolveName(A a) { ... }
If you used B here for no good reason, then you would unnecessarily cripple your method. It could have worked for any A, but it works only for B.
try reading this: Polymorphism
In your short example there's no real advantage,.
But in general your question is about what polymorphism is good for?
And the answer goes back to the need of OOP methodology.
In short it gives you the ability to encapsulate and abstract the implementation from the usage, and can help you I the future to replace the implementation without a need to change the usage.
For more details see http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
In that example, I don't think you can talk about an advantage (or disadvantage), because your two lines of code each do something very different.
If the type of variable a is A, then a.b refers to the field b with the value 10.
But if you change the type of a to B then a.b refers to a totally different field, the one declared inside B, with the value 12.
If instead b was a method, then the one declared in B would "override" the one declared in A, which is a very different situation. e.g.
class A
{
public int b() { return 10; };
}
class B extends A
{
public int b() { return 12; }
}
And the calling code would be:
A a=new B(); //line1
//B a=new B();//line2
System.our.println(a.b());
That is, we call the method b to get the return value. Now it makes no difference to the behaviour whether the type of a is A or B. What matters is the type of object that a refers to, which is always B and hence always has the behaviour defined in B, so it will print 12 regardless.
The advantage of this is that you can have a collection of objects (e.g. various kinds of vehicle) and they can be a mixture of cars, boats, trains etc. Each has its own implementation of the start method, so you can treat them all the same way.
Although generally it's clearer to define such methods in an interface, rather than a class. There is no general way to start a vehicle, so no reason to have a base class that has a meaningless implementation of start. Instead you just use an interface to declare the "shape" of the method without giving it any implementation.

Categories