I have the following interfaces (in Java, but it's more of an OO question, not language-specific, I'm interested in answers for any language)
public interface A {
int foo();
}
and
public interface B {
char foo();
}
If I now want to make the following class:
public class C implements A,B{
public int foo() {
return 0;
}
public char foo() {
return 0;
}
}
This won't compile because the methods are conflicting. Is there any way to make this work, or something with the same meaning (of course without modifying A or B, that would be trivial)?
No, the return type cannot be a deciding factor in making a method signature unique because you do not need to assign the returned value to anything, the compiler wouldn't know what to do in that case.
Concrete example:
...
C object = new C();
object.foo();
...
Which foo did I just call? Can't tell.
To make this work you'll need to have either different method names or different parameter types in the interface methods.
EDIT: assuming you have no control over the interfaces A and B (library classes or similar) this is the solution I'd take if I wanted to implement them in the same class:
public class C {
private objectA = new AImpl();
private objectB = new BImpl();
// Work with the objects here
private class AImpl implements A {
public int foo() {
// ...
}
}
private class BImpl implements B {
public char foo() {
// ...
}
}
}
The common solution is to give each method a different name. Avoid generic names that have a high chance of naming collision with another interface.
This problem is present because in OOP, is considered the existence of more one method with the same name but with different parameters and not by return type.
The problem is not the interface, the problem is the class.
Overloading comes with parameters.
There are several solutions to this problem in use. I am working on the assumption that these are independent interfaces, that the intention is multiple interface (implementation of two unrelated interfaces on the same object) and that overloading has nothing to do with it.
The solutions I am aware of are:
1. Scoping. A reference to foo() can be qualified as A.foo() or B.foo() to determine which is required.
1. Namespaces. The interfaces are inherited inside a namespace constructed for the purpose, and all references to foo() must be preceded by a namespace, eg A::foo(), B::foo().
1. Aliasing. One or both of the foo() methods are explicitly renamed when inherited. Calls become something like A_foo() and B_foo().
Ada certainly had a mechanism like this, and I think some variants of Pascal did too. I can find more examples if it's important.
Related
Is there any way to define methods via method references, as demonstrated by the following imaginary code (and imaginary syntax)?
class A
{
public Sometype somefunction(Argtype arg)
{ ... return somevalue; ..}
}
class B
{
public Sometype method = A::somefunction;
}
or
class C
{
public Sometype method(Argtype arg) = A::somefunction;
}
A similar feature would seem quite useful to me. Methods are known at compile time, so any definition in class B or C might simply (after a type check) take over a reference to an already known method in A. The advantage: faster calls (one less required than even in a direct call from a new method) - where I am not sure whether Java compilers do not optimize anyway?
Is there any way to achieve that already now in Java (if so, it has evaded my search successfully)? Or are there good reasons not to introduce that to Java? Are there any workarounds which provide similar performance advantage?
PS: I get the message that similar question titles have been downvoted and/or closed. If this applies here, too, please help me to understand why. Thanks in advance!
This question can be split in 2 different ones.
How can I use class A methods from other classes
How can I specify the return type of a method at runtime
Regarding the first one, take a look at Java inheritance, polymorphism, abstract classes and interfaces.
I would have defined class A as abstract:
abstract class A{
public Sometype somefunction(Argtype arg)
{ ... return somevalue; ..}
}
and B, C extends it:
class B extends A{
}
In this way B and C inherits all the methods implemented in A and you can perform something like this:
B b = new B();
b.somefunction(arg);
Moreover, referring to the second question if you don't know the return type of this method at compile time you can exploit java generics (if polymorphism isn't enough). In this way class A becomes:
abstract class A{
public T somefunction(Class<T> type)
{ ... return somevalue; ..}
}
and the previous example code becomes:
B b = new B();
b.somefunction(String.class);
You could do something like this:
class A {
public static Sometype someStaticFunction(Argtype aArg) {
...
}
public Sometype someNonStaticFunction(Argtype aArg) {
...
}
}
class B {
private Function<Argtype, Sometype> mStaticFunction = A::someStaticFunction;
private Function<Argtype, Sometype> mNonStaticFunction = new A()::someNonStaticFunction;
public Sometype applyStatic(Argtype aArg) {
return mStaticFunction.apply(aArg);
}
public Sometype applyNonStatic(Argtype aArg) {
return mNonStaticFunction.apply(aArg);
}
}
However I don't see any point in this, regrading design, performance or any other aspects.
This question might resemble cast the Parent object to Child object in C# but it is about C# and I have a question about Java.
I am also aiming to make a generic builder. The generic builder should only build the parts of the abstract object and the children all manage the induvidual implementations of the abstract class.
abstract class GenericBuilder<B extends GenericBuilder>
{
//lots of build methods
public B lastBuildingMethodInTheChain(Object someValue)
{
//assignment
return this;//<-- is not allowed!
}
}
But when I put in a cast:return (B) this; it is fine.
The cast is something I want to prevent, but this also restricts the children builders from using their special methods.
The last thing makes sense because the Generic type is only known at runtime, but I have no clue how to write it so that it would work at compile time.
Thank you!
You can see an example of the typesafe progressive narrowing pattern (a name that I probably just made up) in various Guava builder methods. In the end, the cast is necessary, but you can hide it reasonably well like so:
#SuppressWarnings("unchecked")
private <B1 extends B> GenericBuilder<B1> me() {
return (GenericBuilder<B1>) this;
}
used like so:
public B lastBuildingMethodInTheChain(Object someValue) {
B self = me();
self.assignWhatever = someValue;
return me;
}
(I'm not 100% sure this will work exactly as-is because of the extra weirdness you've got, with the object being parameterized as a subclass of itself.)
Here are some similar examples to draw from:
Subclassing a Java Builder class
http://egalluzzo.blogspot.com/2010/06/using-inheritance-with-fluent.html
http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ205
Note the use of the getThis() method which avoids the cast.
The correct way to declare GenericBuilder is with an f-bound type:
abstract class GenericBuilder<B extends GenericBuilder<B>> {
public B lastBuildingMethodInTheChain(Object someValue) {
// assignment
return (B) this;
}
}
You can't avoid the cast, as the compiler needs it to know that this generic builder is actually the concrete builder of the generic type parameter.
You can extend the generic builder as follows:
public class ConcreteBuilder1 extends GenericBuilder<ConcreteBuilder1> {
}
It is reasonable to assume the cast is safe. The only way for the cast to fail would be to declare i.e.:
public class ConcreteBuilder2 extends GenericBuilder<ConcreteBuilder3> {
}
But why would you ever do that?
This makes no sense. this is a GenericBuilder, and B extends GenericBuilder, so how are you going to return this (since GenericBuilder does not extend itself (tautologically)
let me first explain what i want to say actually
Suppose a class Sub inheriting the class Super.
now we can excess all no private members of class Super within class Sub. now Suppose the case
class Super{
private int id;
public int getId()
{
return id;
}
}
class Sub extends Super {
public static void main(String args[]){
Sub sub = new Sub();
System.out.println(sub.getId());
}
}
I know that creating Sub class object will call Super class constructor too.
But the job of constructor is to initialize the fields only -- not to allocate the memory to the object.
Moreover in case of abstract class where the initialization is not allowed we can still use the instance variable of abstract class.
The memory to instance variable will be assigned at time of instance creation only.
Than how can we use the instance fields without even creating the instance.
Doesn't it violets the oops concept..??
Please help over this. And thanks in advance.
I think you're confused about what happens when you use the extends keyword. What that keyword means is that a Sub is a more-specific kind of Super. By the Liskov Substitution Principle, all of the properties of Super must hold for Sub as well. That means that all of Super's private members (methods and properties) are present in an instance of Sub. It's just that for organizational reasons, the developer of Super decided that they didn't want any derived classes messing around with it directly.
Now, how does this relate to memory allocation? In the case of Java, you are correct that the constructor does not allocate memory. It just initializes the fields. The memory allocation is handled by the runtime, and it allocates enough for the whole picture. Remember, a Sub is a Super and then some. So it allocates enough memory to hold everything from the entire inheritance chain all the way back up through java.lang.Object.
abstract classes can, in fact be initialized, or even force their derived classes to initialize their members. For example:
public abstract class Super {
private int id;
public Super(int id) {
this.id = id;
}
public int getId() { return this.id; }
}
public class Sub extends Super {
public Sub() {
super(5); // failure to call this constructor is a compiler error
}
}
Now, because Sub can't see Super's private id field, it's free to declare a new one of its own. This does not override Super's field. Any of Super's methods that use that field will still use the one from Super. This could be a little confusing, so the best advice is don't think of it that way. Generally, you'll want to override methods not fields.
I totally agree with the answer of Ian. Totally. Regarding the title of your question,
Does inheritance violates the basic law of oops..?
the answer is it depends. There is a kind of inheritance that violates encapsulation principle: implementation inheritance.
You're using implementation inheritance every time you inherit (through extends primitive) from a class that is not marked as abstract. In that case, to know how to implement your subclass, you need to know the implementation (a.k.a. the code) of methods of the base class. When you override a method, you have to know exactly which is the behavior of that method in the base class. This kind of code reuse is often referred to as white-box reuse.
Quoting the GoF's book, Design Pattern:
Parent classes often define at least part of their subclasses' physical representation. Because inheritance exposes a subclass to details of its parent's implementation, it's often said that "inheritance breaks encapsulation".
So, to reduce implementation dependencies, you have to follow one of the principles of reusable object-oriented design, which is:
Program to an interface, not an implementation
inheritance only concern about what and how is accomplished, not what is promised. If you violate the promises of the base class, what will happen? is there any guarantee that makes you sure it's compatible? -even your compiler will not understand this mistake and you will face a bug in your codes. Such as:
class DoubleEndedQueue {
void insertFront(Node node){
// ...
// insert node infornt of queue
}
void insertEnd(Node node){
// ...
// insert a node at the end of queue
}
void deleteFront(Node node){
// ...
// delete the node infront of queue
}
void deleteEnd(Node node){
// ...
// delete the node at the end of queue
}
}
class Stack extends DoubleEndedQueue {
// ...
}
if the class wants to use inheritance with aim of code reuse, It may inherit a behavior that violates its principal, such as insertFront. Let's also see another code example:
public class DataHashSet extends HashSet {
private int addCount = 0;
public function DataHashSet(Collection collection) {
super(collection);
}
public function DataHashSet(int initCapacity, float loadFactor) {
super(initCapacity, loadFactor);
}
public boolean function add(Object object) {
addCount++;
return super.add(object);
}
public boolean function addAll(Collection collection) {
addCount += collection.size();
return super.addAll(collection);
}
public int function getAddCount(Object object) {
return addCount;
}
}
I just reimplement HashSet with DataHashSet class in order to keep track of inserts. In fact, DataHashSet inherit and is a subtype of HashSet. we can instead of HashSet just pass DataHashSet(in java is possible). Also, I do override some of the methods of the base class. Is this legitimate from Liskov substitution principle? As I do not make any changes in the behavior of base class just add a track to insert actions, It seems perfectly legitimate. But, I will argue this is obviously a risky inheritance and a buggy code. First, we should see what exactly add method do. add one unit to related property and call parent class method. There is a problem with that called yo-yo. Look at addAll method, first, it adds collection size to related property then call addAll in the parent, but what exactly parent addAll do? It will call add method several times(loop over the collection), which add will be called? the add in the current class, so, the size of count will be added twice. once when you call addAll and second when parent class will call add method in the child class, that's why we call it yo-yo problem. And another example, imagine:
class A {
void foo(){
...
this.bar();
...
}
void bar(){
...
}
}
class B extends A {
//override bar
void bar(){
...
}
}
class C {
void bazz(){
B b = new B();
// which bar would be called?
B.foo();
}
}
As you see in bazz method which bar will be called? the second one the bar in class B will be called. but, what is the problem here? the problem is foo method in class A will not know anything about the override of bar method in class B, Then your invariants may be violated. because foo may expect the only behavior of bar method that is in own class, not something is overridden. This problem is called fragile base-class problem.
I'm sorry if this question may be asked all the time, but I searched and couldn't find an sufficient answer.
How to disable inheritance of private members/fields if they are being accessed by a public member/method?
So consider this:
public class A {
private MemberA a = new MemberA();
public void foo(TypeA x) {
a.methodCall(); //access to a
}
}
public class B extends A {
private MemberB b = new MemberB();
public void foo(TypeB x) {
b.methodCall();
}
}
If you hit the debugger you'll see, that B has a field a by type MemberA. That's in compliance with Java rules because if a public member has access to a private member it will be inherited.
But in B "a" is useless and only taking memory - even if you don't instanciate it in the constructor of B, because B calls it's super constructor and it has to be instanciated in A because a has very much use for a.
I need to have same method names for A and B and they have to be public, but since they do fundamentally different things but also share common logic B needs to be inherited from A.
So basically, I need to know how to overload and override a method the same time. Or duplicate code. What to do?
This situation -- where a class has data members that you do not want to inherit -- is called the "Refused Bequest" antipattern, and what it generally means is that your inheritance relationship is wrong. Rather than having B extend A, you need an interface C that both implement independently. If there is significant implementation that you do want to share, then perhaps you could introduce an abstract base class that A and B could share.
Alternatively, it could also be that MemberA and MemberB (not A and B) share the common interface (or abstract class), say "Member", including methodCall(). You could then do
public class A {
protected Member myMember; // sounds like an Austin Powers movie...
// in the constructor
myMember= new A();
}
while, in class B, the constructor does this instead: (or use DI, etc...)
myMember = new B();
and in foo(), which need not be overloaded, you call myMember.methodCall().
Without knowing your problem it's hard to say if this approach or #Ernest's is better. In either case you are looking for common functionality, and it will likely be the same amount of work.
Basicaly I have a need for several methods that do the same thing but with different parameters the sub-classes can chose from, and still force the implementation.
Is this a correct approach/design ?
EDIT: I have edited the addItem() body, these methods contain the final logic that is used to handle the passed parameters
public abstract Class A {
public abstract void addItemImpl()
addItem(String s) {
// do stuff
}
addItem(Collection c) {
// do stuff
}
addItem(Item item) {
// do stuff
}
}
public Class B extends A {
addItemImpl() {
addItem("text, text2")
}
}
public Class C extends A {
addItemImpl() {
addItem([item, item2])
}
}
No, this will not work.
You will not be able to define the "doStuff()" method because you have to handle the parameters. You provide not enough information to give you detailed help. But it's possible that generics might come in handy:
public abstract Class A<T> {
public addItem(T t) {
// dostuff with t
}
}
public Class B extends A<String> {
}
public Class C extends A<Collection> {
}
This is a perfect case for: Favor composition over inheritance.
Your subclasses don't fully benefit from the superclass and don't depend on its implementation details. Then define an interface for the contract B and C must obey (addItemImpl()) and compose them with A.
Ask yourself: is B really an A? is C really and A?
What you have is technically correct, but with out knowing what addItem actually does it is difficult to know if this is the best solution. My guess would be that there probably is a better way.
If addItem essentially set values to be used in the doStuff, I would just do that work in the Class B and C instead. Any others that need to do it the same way as B could extend it instead of A.
Edit: Based on your edit, I would say this is probably a bad example to use an abstract class. There is no truely shared functionality. An interface would be more appropriate as you need a different implementation for each. You are just trying to hide that inside an abstract class. I would change A to an interface along with using generics.
Only go the abstract class route if there is actually shared code that is exactly the same in all the classes without having to do any tricks to make it work (like above).
If you need force implementation for few methods, then Abstract methods are ideal.
But be careful only the very first Non-Abstract sub-class of the Super-class is bound to implement all the abstract methods in it....