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.
Related
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.
Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"
There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);
No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.
With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}
If I have two classes, A and B,
public class A {
public int test() {
return 1;
}
}
public class B extends A{
public int test() {
return 2;
}
}
If I do: A a1 = new B(), then a1.test() returns 2 instead of 1 as desired.
Is this just a quirk of Java, or is there some reason for this behavior?
This is called polymorphism. At runtime the correct method will be called according to the "real" type of a1, which is B in this case.
As wikipedia puts it nicely:
The primary usage of polymorphism in industry (object-oriented
programming theory) is the ability of objects belonging to different
types to respond to method, field, or property calls of the same name,
each one according to an appropriate type-specific behavior. The
programmer (and the program) does not have to know the exact type of
the object in advance, and so the exact behavior is determined at
run-time (this is called late binding or dynamic binding).
No, that is correct (it is due to polymorphism). All method calls operate on object, not reference type.
Here your object is of type B, so test method of class B will be called.
This is polymorphism and more specifically in Java overriding. If you want to invoke Class A's test method from Class B then you need to use super to invoke the super classes method. e.g:
public class B extends A{
public int test() {
return super.test();
}
This is intended behavior. The method test() in class B is overriding the method test() of class A.
For
A a1 = new B();
a1 is pointing towards the object of B which is the real type at run-time. Hence value is printed from Object B.
A obj = new A();
obj.test()
will return 1
A obj = new B();
obj.test()
will return 2
B obj = new B();
obj.test()
will return 2
As stated in other answers this is how polymorphism works.
This post may make things a bit clearer
Java uses dynamic binding (or late binding), so the method of B is called, not A. This is the opposite of static binding. There is a nice example here.
You declare your object as A but your instance is B. So the method which will be called is from class B. B extends A(we can say that A is parent for B) if you will comment method test in B and then recall this method, in this case the method invoked will be test from A class and will return 1.
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 three classes (class A, class B, and class C).
Class A calls an instance of B and runs start().
Class B extends Thread, so when start() is called, anything in the run() method is executed.
In the run() thread, there is an instance of class C.
Is there anyway to allow a method in Class C to call a method in Class A, without instantiating a new instance of Class A?
Since I can't extend class A to class B (because "Thread" is already extended), I don't know how I'd go about doing this.
Sorry for being vague, but my project features far too much code and is way too complicated to provide a direct code example.
Thanks!
So you have
class A {
void run()
{
new B().start();
}
}
class B extends Thread {
public void run(){
C c = new C();
c.do something with A .. }
}
You can pass the caller, which might get ugly, as you have to pass A all the way down to C through B:
class A {
void run()
{
new B(this).start();
}
}
class B extends Thread {
public void run(A a){
C c = new C();
c.do something(a)..
}
}
or simplify, especially if B and C have no other reason for being:
class A {
public void run()
{
this.do something() ...
}
}
this is a circular dependency, a very bad thing in OOP in my (modest) opinion.
You must refactor your code to provide a common class for A and C.
The best way might be for class B's start to be overloaded to take a parameter (A, or better yet, an interface implemented by A). Then B can either store that for retrieval by C (if it's an inner class) or pass it to C's constructor...
EDIT:
Although as the commenter mentioned overriding the constructor would work, it doesn't fit the parameters of the question which was phrased in such a way that B already existed, so my suggestion is to overload the start() like this:
b.start(A aParam) {
a=aParam;
start();
}
This version is NOT thread safe however. B's constructor works if B is actually instantiated every time, or if C is instantiated when b starts, then it could be passed to C's constructor as it's instantiated.
By the way, extending thread is not generally as good as implementing runnable for quite a few reasons.
Another way to utilize thread behavior in java is to implement Runnable. Conceivably you could extend A, and implement Runnable, and use:
Thread t = new Thread( b )
t.start();
Seems ugly from a OOP point of view, but it could conceivably make sense under certain circumstances. The other two answers seem a bit more sensible, but figured that this could be considered.