It seems that Java 8 allows full fledged inheritance with a simple framework as below, using Static and Default methods on interfaces.
While its always possible to misuse and write stupid code, these new features make it quite easy to achieve multiple inheritance, even if the designers of the language meant to stay away from it.
Is this a simple implementation of Multiple Inheritance using Interfaces as base classes, or a misuse of the language?
Did Java designers go too far in allowing this?
package PseudoMultipleInheritance;
import java.util.HashMap;
abstract class InstanceMap<T,T2>
{
HashMap<Object,Object> instances = new HashMap<Object, Object>();
abstract T2 createMembersInstance();
T2 getMembersInstance(T thisObject )
{
if ( !instances.containsKey(thisObject) )
instances.put(thisObject,createMembersInstance());
return (T2) instances.get(thisObject);
}
}
interface A
{
class Members
{
int x; // just an example of an inheritable member
}
InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() { A.Members createMembersInstance() {return new A.Members(); }};
default A.Members thisA() { return instanceMap.getMembersInstance(this); }
default int getX()
{
return thisA().x; // // just an example of an inheritable getter
}
default void setX(int x)
{
thisA().x = x; // just an example of an inheritable setter
}
}
interface B
{
class Members
{
int y; // just an example of an inheritable member
}
InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() { B.Members createMembersInstance() {return new B.Members();} };
default B.Members thisB() { return instanceMap.getMembersInstance(this); }
default int getYLastDigit()
{
return thisB().y % 10; // just an example of an inheritable function
}
default void incrementY(int x)
{
thisB().y += x; // just an example of an inheritable function
}
}
class C implements A, B
{
}
public class Example04AlmostMultipleInheritance {
public static void main(String[] args) {
C c1 = new C();
C c2 = new C();
c1.setX(5);
c2.setX(3);
System.out.println(c1.getX()); // prints 5
System.out.println(c2.getX()); // prints 3
c1.incrementY(99);
System.out.println(c1.getYLastDigit()); // prints 9
}
}
///////////////////////////////////////////////////
Or for yet another option:
interface A
{
class Members
{
public int x; // just an example of an inheritable member
void showX() { System.out.println(x); } // just an example of an inheritable function
}
InstanceMap<A,A.Members> instanceMap = new InstanceMap<A, A.Members>() { A.Members createMembersInstance() {return new A.Members(); }};
default A.Members getA() { return instanceMap.getMembersInstance(this); }
}
interface B
{
class Members
{
int y; // just an example of an inheritable member
}
InstanceMap<B,B.Members> instanceMap = new InstanceMap<B, B.Members>() { B.Members createMembersInstance() {return new B.Members();} };
default B.Members getB() { return instanceMap.getMembersInstance(this); }
}
class C implements A, B
{
}
public class Example04AlmostMultipleInheritance {
public static void main(String[] args) {
C c1 = new C();
C c2 = new C();
c1.getA().x = 5;
c2.getA().x = 3;
c1.getA().showX(); // prints 5
c2.getA().showX(); // prints 3
c1.getB().y = 99;
System.out.println(c1.getB().y % 10); // prints 9
}
}
Implementing an interface is not inheritance. It's as simple as that.
what if someone implements both your interfaces but supplies a different implementation than the default one?
So no, this is not multiple inheritance, It's simply a way to write your code that depends on nobody actually implementing their own version of the default methods. Which means that it depends on people not actually using interfaces the way they're supposed to, because they are supposed to be able to implement their own methods instead of the defaults, but if they actually do that your "multiple inheritance" does not work as expected.
So I'd actually consider this to be misuse of the language.
It is A form of multiple inheritance, but it's not the "Diamond Problem" that is usually brought up when discussing multiple inheritence. Java's implementation is almost the same as Scala's solution to the same thing, which is somewhat similar to how Python implements multiple inheritance.
no, see example of multiple inheritance here: http://java.dzone.com/articles/interface-default-methods-java
Related
How to write a java program making use of static variables such that only an even number of objects of a certain class X can be instantiate.
E.g. Only allowed to create 2 or 4 or 6....(etc.) objects of that class but never 1 or 3 or 5 (etc.)
I am going to write this an "instance" version of the question as global state should be avoided.
package thing; // Use packages.
public class Thing {
// Hide this constructor.
/* pp */ Thing() {
}
}
package thing;
// We need this because single return value.
// Alternatively, you could have a pair of Consumers
// or a BiConsumer (which apparently is a thing,
// notably Map.forEach and Collector.accumulator).
public interface ThingPair {
Thing a();
Thing b();
}
package thing;
public class Things {
// Return a pair of things at once.
public ThingPair makePair() {
Thing a = new Thing();
Thing b = new Thing();
return new ThingPair() {
public Thing a() { return a; }
public Thing b() { return b; }
}
}
}
suppose in Eclipse I have three packages with the following classes in each:
Packages: Classes
Head: head.java
Body: arms.java
Legs: feet.java
I want to define class info in brain.java and pass it through methods to the other classes (arms.java and feet.java) and update the contents of info.
class info {
// some vars such as bools,ints,strings
}
For example, have updateArms be a method defined in arms.java. I want to do the following in brain.java:
arms.updateArms( info );
I am having trouble finding how to first define a class that behaves this way, and secondly how to pass it as a parameter to another linked class.
First, you should learn about Java naming convention.
For example, package should be head, and the class should be Head.
Go back to your design: In OOP, we see the program as interactions between object instances.
In your example, it may look like:
class Arm {
void moveUp(SomeInfo info) {
...
}
}
class Brain {
private Arm leftArm;
private Arm rightArm;
void reachForward() {
rightArm.moveUp(...);
}
void connectLeftArm(Arm arm) {
this.leftArm = arm;
}
//....
}
class Body {
Brain brain;
Arm leftArm;
Arm rightArm;
public Body() {
this.brain = new Brain();
this.leftArm = new Arm();
this.rightArm = new Arm();
this.brain.connectLeftArm(this.leftArm);
this.brain.connectRightArm(this.rightArm);
}
}
I wish this demonstrate the difference of way of thinking.
If you start get used to the way OOP see things, then you can take next step in refining your design (e.g. by different design pattern)
You can achieve this using Inheritance.
Inheritance can be defined as the process where one class acquires the properties (methods and fields) of another. With the use of inheritance the information is made manageable in a hierarchical order. The class which inherits the properties of other is known as subclass (derived class, child class) and the class whose properties are inherited is known as superclass (base class, parent class).
Sample Code helps you how to use the methods and properties of other classes.
class Calculation {
int z;
public void addition(int x, int y) {
z = x + y;
System.out.println("The sum of the given numbers:"+z);
}
public void Subtraction(int x, int y) {
z = x - y;
System.out.println("The difference between the given numbers:"+z);
}
}
public class My_Calculation extends Calculation {
public void multiplication(int x, int y) {
z = x * y;
System.out.println("The product of the given numbers:"+z);
}
public static void main(String args[]) {
int a = 20, b = 10;
My_Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
demo.multiplication(a, b);
}
}
This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}
Is it possible through some method to assign a function to a variable in Java, like in PHP or JavaScript?
...Or does this area works on a different way when it comes to Java?
In Java you have Method and MethodHandles which can invoke a method via reflection but that is not supported in the language yet.
In Java 8, you will be able to use references to methods.
In today's java, no you can't.
The nearest you have is the interface : you don't store a function but the implementation of an interface defining the wanted function.
A typical example is the implementation of the Comparator interface :
Comparator<ProductSearchResult> c = new Comparator<ProductSearchResult>() {
public int compare(ProductSearchResult result1, ProductSearchResult result2) {
return result1.product.getRsId().compareTo(result2.product.getRsId());
}
};
Collections.sort(groupResults, c); // I pass a function, wrapped in my Comparator implementation
The nearest you have are inner classes combined with interfaces. These can carry not only one but many functions (methods) that can be delegated back to the master class methods if preferred. But this solution may easily be too heavyweight:
class Main {
interface X {
void doX();
}
class Ref1 implements X {
void doX() { doA(); };
}
class Ref2 implements X {
void doX() { doB(); };
}
void doA() { };
void doB() { };
void demo() {
X x = new Ref1();
x.doX();
}
}
This simulates something similar to Lambdas ... (you'll need a little more casting if you use anything other than Strings, but I'm keeping the example brief) ...
public class MyTest {
public static void main(String[] args) {
Lambda l = new Lambda() { public Object func(Object x)
{ return "Hello " + x; }
};
System.out.println(l.func("Bob"));
System.out.println(nowTryFromMethod(l));
System.out.println((new Lambda() { public Object func(Object x)
{ return "Goodbye " + x; }
}).func("Harry"));
}
private static Object nowTryFromMethod(Lambda l) {
return l.func("Jerry");
}
}
class Lambda {
public Object func(Object x) { return null; }
}
Output:
Hello Bob
Hello Jerry
Goodbye Harry
Update
Java supports reference to functions which is called Lambda from version 1.8
Java does NOT support that.
However, you can do that in JVM-Languages very comfortably, e.g. in Groovy.
Or you take a look at the command-pattern.
I am trying to do something I would not normally do, it is a bit odd, but I'd like to make it work. Essentially I have a factory that has to create objects by calling the constructor with different types of data (A and B take different types in the code below). I seem to have gotten my self stuck going down the generics route (I do need the code to be as compile time typesafe as possible). I am not opposed to writing the code differently (I'd like to keep the idea of the factory if possible, and I do not want to have to add in casts - so the "data" parameter cannot be an "Object").
Any thoughts on how to fix the code with generics or an alternative way of doing it that meets my requirements?
(Technically this is homework, but I am the instructor trying out something new... so it isn't really homework :-)
public class Main2
{
public static void main(String[] args)
{
X<?> x;
x = XFactory.makeX(0, "Hello");
x.foo();
x = XFactory.makeX(1, Integer.valueOf(42));
x.foo();
}
}
class XFactory
{
public static <T> X<T> makeX(final int i,
final T data)
{
final X<T> x;
if(i == 0)
{
// compiler error: cannot find symbol constructor A(T)
x = new A(data);
}
else
{
// compiler error: cannot find symbol constructor B(T)
x = new B(data);
}
return (x);
}
}
interface X<T>
{
void foo();
}
class A
implements X<String>
{
A(final String s)
{
}
public void foo()
{
System.out.println("A.foo");
}
}
class B
implements X<Integer>
{
B(final Integer i)
{
}
public void foo()
{
System.out.println("B.foo");
}
}
I don't see a way to make it work. I don't really think it should work either. When calling your makeX() function the calling code needs to know what integer parameter corresponds to what type of data to pass in. IOW, your abstraction is very leaky in the first place, and what you're really implementing is a rudimentary form of polymorphism, which you might as well use method overloading for, i.e.:
X makeX(String data) {
return new A(data);
}
X makeX(Integer data) {
return new B(data);
}
Of course it's a toy problem and all that. One way to make it work would be to make the client aware of implementation classes and add a Class<T> argument that you instantiate through reflection. But I suppose that would be kind of defeating the purpose.
I don't think what you're trying to do is possible without casting.
With casting, you have two options
if(i == 0)
{
x = new A((Integer)data);
}
else
{
x = new B((String)data);
}
}
or
class A
implements X<String>
{
A(final Object s)
{
}
}
...
class B
implements X<Integer>
{
B(final Object i)
{
}
}
Probably the closest thing you could get whilst retaining static type safety and having lazy construction is:
public static void main(String[] args) {
X<?> x;
x = aFactory("Hello").makeX();
x.foo();
x = bFactory(42).makeX();
x.foo();
}
private static XFactory aFactory(final String value) {
return new XFactory() { public X<?> makeX() {
return new A(value);
}};
}
public static XFactory bFactory(final Integer value) {
return new XFactory() { public X<?> makeX() {
return new B(value);
}};
}
interface XFactory() {
X<?> makeX();
}
So we create an instance of an abstract factory that creates the appropriate instance with the appropriate argument. As a factory, the product is only constructed on demand.
Clearly something had to give. What would you expect XFactory.makeX(1, "Hello") to do?
This is not possible without casting. As I have said elsewhere - generics don't remove the need for casting, but they mean that you can do all the casting in one place.
In the setup you describe, the factory method is exactly where all the under-the-hood work takes place. It's the spot where your code tells the compiler "I know you don't know what these types are, but I do, so relax.
It's entirely legit for your factory method to know that if i==1, then the data must be be of type Integer, and to check/enforce this with casting.