Say, I have an abstract class A which is extended by child classes B,C & D.
Is there a way to supply an argument that accepts only B & C using generics.
As far as I know, we can combine a class and interface in generics. But can we combine two child classes?
As I said in the comment, it's not possible. Depending on what the problem that you are trying to solve is, you could do something like this:
class Foo {
public bar(B obj) { fooBar(obj); }
public bar(C obj) { fooBar(obj); }
private acceptBAndC(A obj) { /* obj can be B or C */ }
}
Then you still share the code between implementations for B and C while Dcannot be passed to fooBar().
But IMHO the cleaner solution would be to introduce a new abstract class BOrC that is derived from A and have B and C inherit from that class (but of course not D).
But baring sufficient information, I can only guess if that fits your use case.
Related
I have different objects(Object A and object B). But some of the objects' fields are same. I can't change the object classes( i mean i cant write a implement/extends condition for them). I want to pass the objects to a method which uses the objects' fields They have same fields. I don't want to overloading. Which design is the most suitable for this?.
A obj1 = new A();
B obj2 = new B();
update(obj1);
update(obj2);
// my function
public <T extends myInterface> void update(T obj)
{
obj.field+=1;
}
public interface myInterface{
int field=0;
}
--------------
public class A{
int field;
.... // smt else
}
--------------
public class B{
int field;
.... // smt else
}
If you have two classes which do not implement a common interface or share a common base class, you can't really pass them to your function.
The fact that they have a common field doesn't matter.
You have 3 workarounds, none of which is really good:
Have your function accept Object type, and check its type (A or B) inside using instanceof. This is ugly and not recommended as any class can be passed inside, and also your code has to check it's type all the time.
Have your function accept Object type, Use reflection to access field with specific name, in this way:
Field field = obj.getClass().getDeclaredField('myfeild');
Object value = field.get(obj);
This is better in that your code doesn't have to check types, but more unsafe. Any class can be passed to your function, and there's some dark magic which relies on static field names. If field name changes, your code breaks.
Perhaps the best - Implement a wrapper for your objects. It will have two constructors, one for class A and one for class B. The wrapper will remember which kind of object resides inside. In its getField function if will have a single if statement. Have your function accept the wrapper type as the argument.
instanceof can be used indentify class of object. Like this:
public <T extends myInterface> void update(Object obj)
{
if ( obj instanceof A )
{
A a = (A)obj;
a.field+=1;
}
if( obj instanceof B )
{
B b = (B)obj;
b.field+=1;
}
}
I have a set of operations. Every operation is a sequence of 2 steps. So, I have a base class which executes these two steps and all the operations extend this base class and provide the actual implementations for the two steps. Ex.
class Base {
Step1 step1;
Step2 step2;
B execute() {
A a = step1.perform();
B b = step2.perform(a);
}
//Set methods...
}
Here Step1 and Step2 are interfaces and one can change the implementations for them to do different things.
I have the following questions:
Every implementation of step2 takes instance of A as input which can also contain a derived type of A. So I need to do a downcast. Is it ok to do a downcast in this case or is there a better way to achieve this?
Some implementations of step2 may not return any value. Is it ok if we have an empty class just for the type hierarchy and other classes extend this class?
Question 1
Yes, that is ok. Every class which extends the class A or implements the interface A (what ever A is) will be "an instance of A". So it is perfectly OK to pass it to a method which needs an object of the type A. Nothing to worry about. This is how you should use interface and inheritance. There are different kind of "specializations" of the same super-class.
Question 2
This is a question of your API design. If you want that this method could return null, you can do this. But you should document it very good!
A very new possibility in Java 8 are so called Optionals. You can use them if a method could return null and you want to force the programmer to keep that in mind. That would be the cleanest (and recommended) way. You can find an example and a description at http://java.dzone.com/articles/optional-java-8-cheat-sheet. Basically you would say that your method perform of the class Step2 will return an Optional instead of the type:
interface Setp2 {
public Optional<B> perform(A a);
}
// the optional will wrap the actual result which could be null
// since Java 8
Optional<B> b = step2.perform(a);
It sounds like you should use generics:
interface Step1<T extends A> {
T perform(T a);
}
interface Step2<T extends A, U extends B> {
U perform(T a);
}
class Base<T extends A, U extends B>>{
Step1<T> step1;
Step2<T, U> step2;
B execute() {
T a = step1.perform();
U b = step2.perform(a);
}
//Set methods...
}
Regarding returning "nothing", the best way is to return null.
If class a extends class b, and class b extends class c, does a inherit from both c and b? If so, in case of conflict between the 2, is there an error or does one override another (and if so, which one)?
Please rename the question if it is unsuitably titled.
EDIT: what I mean by conflict is something like the following:
class c {
int foo;
//Stuff
}
class b extends c {
String foo;
//Stuff
}
class a extends b {
//Stuff
}
Is a.foo a string or an int?
Another edit: So from what I gather, inheritance here is a bit like CSS - the closer the rule is set, the larger priority it has (e.g. inline styles override stylesheets). Is that a good way of considering this, or is it significantly different?
If something exists in both b and c, a will inherit whichever one b uses.
Yes, a inherits from b and c. I don't see how there can be a conflict in this situation since b's method overrides will be valid for a. You may be thinking of the diamond problem that comes from conflicts from multiple inheritance, but that's when you have two different parents, not two parents with one parent being the parent of the other.
You can run into a "soft" diamond problem with interfaces, where two methods have the same signature, but the rules for one method don't match those of another. Since neither interface has an implementation for their methods, there is no compilation problem (that I know of), just a logical problem.
Edit Ah, I've seen your edit regarding variables, and I agree with Jimpanzee's response to it. It's certainly easy to test:
public class Test3 {
public static void main(String[] args) {
MyA myA = new MyA();
System.out.println("foo := " + myA.foo);
}
}
class MyC {
public int foo = 3;
//Stuff
}
class MyB extends MyC {
public String foo = "foo";
//Stuff
}
class MyA extends MyB {
}
well, the rule is as follows.
Any subclass will inherit nearest up its hierarchy. so a will get everything from b. Because everything which is on inheritance stack will be available till b. as b had inherited already everything from its inheritance hierarchy.
Secondly, if b over-rides anything(instance variable/method), then a will see over-ridden version. So in your case a will get String foo.
This answer has a much better example, and points out that doing this sort of thing is considered bad practice. (Eclipse will give you a warning, for example.) Extending your code a bit:
class c {
int foo = 42;
//Stuff
}
class b extends c {
String foo = "foostr";
//Stuff
}
class a extends b {
//Stuff
}
class Main{
public static void main(String[] args){
a mya = new a();
System.out.println(mya.foo);
}
}
Running java Main prints foostr.
In Java only methods are subject to overriding. Everything else is just inherited and there is only the issue of a namespace clash, but everything is still accessible. In your example both foos are accessible in A (I've corrected the class names to make them conform to the strong Java naming conventions):
class C {
int foo;
//Stuff
}
class B extends C {
String foo;
//Stuff
}
class A extends B {
String x = ((B)this).foo;
int i = ((C)this).foo;
}
Yes, it inherits from both c and b.
In order to prevent/avoid conflicts, Java support a single hierarchy model (differently from other OOP languages like C++ which allow multiple-class inheritance model).
I have a kind of specific problem, let's say, that I have
public interface A {
}
//------------------------------
public class B implements A {
static int countx = 0;
}
//----------------------------------
public class C implements A {
static int county = 0;
}
//----------------------------------
public class Arc {
public A from;
public A to;
//========================================
and now I have an object a (which is an instance of Arc) and I want to find out whether it is an instance of B or C and get to the atributes countX or countY (stg like a.from.countX)
any ideas? :)
I think you could use instanceof to solve this issue
as in
if(a instanceof B) return a.countx
if(a instanceof C) return a.county
Your current design is not good from the OOP standpoint. You need some encapsulation and polymorphism. In an OOP language, you don't explicitly check for the type of an object, you arrange for that to happen automatically via dynamic dispatch. So whatever data you need from both B and C, add a method to the interface A that will get that data and then implement the method in B and C accordingly. Also, don't use public instance fields, that breaks encapuslation.
Use instanceof and a typecast:
if (a.from instanceof B) {
B b = (B)a.from;
b.countx;
}
Edit: But you should really not need such a thing! If you do, you can probably redesign it to not produce ugly code like this.
For example you could let your interface A have a method getCount() and let your classes B and C implement these, by returning countx or county.
Edit2: I just noticed that your countx and county members are static! Why would you do that? static means, that they don't "act" upon instances of your class but on your class object (they are "class members"). This means that you can access and modify these variables everywhere by accessing them through A.countx or B.county; you most probably don't want this, because multiple instances of class A will share the same countx!
If you have an object that is an instance of Arc, then how is it also an instance of B or C? I feel like your code is flawed and needs restructuring. For example, as Tudor pointed out, "There is no relation between the classes Arc and A in your hierarchy."
If you simply want to have information about the classes :
getClass().getSuperclass()
Regards,
Erwald
Think about it like this :
What makes me want to discriminate between a B and a C ? Is it an operation? If so, just implement those operations appropriately in B vs C and let dynamic dispatch take care of the rest.
interface Operation {
public Result operate(String[] args);
}
class A implements Operation {
#Override
public Result operate(String[] args) {
//I need to do some special calculations for an A...
for(String arg : args) {
}
.
.
.
}
}
class B implements Operation {
#Override
public Result operate(String[] args) {
//i know this does nothing so return the empty result
return Result.EMPTY;
}
}
Resist the tempation to use instanceof. In most cases you don't need it - and its not OO.
What is the best use of Inheritance, other than it will reduce redundant code!
Let us take an example
Class A:Base Class
Class B:Sub Class
and Class C.
CLASS A
^
| And CLASS C
|
|
CLASS B
i can use methods from Class A, in Class B by inheritance.
in the same i can use the methods from Class A, in Class C, by creating instance of Class A.(say A is Public)
using inheritance, only reduce creating new Object/Instance?
Plz help me to better understand!
A great benefit is polymorphism. If classes B and C both inherit from A, then whenever an object of type A is required, it can be replaced by either an object of type B or an object of type C. Assuming the corresponding methods are overriden in B and C, this is very handy to get different behavior depending on which object you pass.
Example:
class A {
public void foo() { System.out.println("A"); }
}
class B extends A {
public void foo() { System.out.println("B"); }
}
class C extends A {
public void foo() { System.out.println("C"); }
}
Then:
public static void printMessage(A obj) {
obj.foo();
}
public static void main(String[] args) {
A b = new B();
printMessage(b); // prints 'B'
A c = new C();
printMessage(c); // prints 'C'
}
The main point of inheritance is polymorphism: to allow other classes to use an instance of ClassB knowing only that it can be used as a ClassA.
My favourite example is streams - I could easily write a copyStream method taking an InputStream and an OutputStream for example, using only the methods declared on those types. Then I could copy a FileInputStream to a ByteArrayOutputStream, or use network-related streams etc, all without changing any of the code in the copyStream method.
The main reason to use inheritance is not to remove redundant code.
Inheritance and all magic made possible is a key, central point in OOP. Extending a class doesn't only allow you to use its functionality, but also modify (by polimorphism) and add more functionality.
The difference comes with the need to understand the ability to pass class B into functions that act on class A. In this sense B is-a type of A where class C has or owns A. The difference is small and only significant in certain circumstance.
That is not to say that the difference is often made explicit in code tbh. Often people will inherit when they really want ownership and sometimes they do ownership when an object really is-a type of something else.