I am just wandering if following is an odd behaviour.
public interface TestInterfaceTwo {
public void sayBye();
}
public interface TestInterfaceOne {
public void sayHI();
}
public abstract class TestIntefaceClass implements TestInterfaceOne, TestInterfaceTwo {
#Override
public void sayHI() {
System.out.println("HI");
}
#Override
public void sayBye() {
System.out.println("Bye");
}
}
public class InterfaceImplementer extends TestIntefaceClass{
#Override
public void sayHI() {
System.out.println("SAY HI");
}
}
public static void main(String[] args) {
InterfaceImplementer impl = new InterfaceImplementer();
TestInterfaceOne impl1 = new InterfaceImplementer();
TestInterfaceTwo impl2 = new InterfaceImplementer();
TestIntefaceClass impl3 = new InterfaceImplementer();
impl.sayHI();
impl.sayBye();
impl1.sayHI();
impl2.sayBye();
impl.sayBye();
impl3.sayBye();
impl3.sayHI();
}
These calls result the following
SAY HI
Bye
SAY HI
Bye
Bye
Bye
SAY HI
I needed to know if interface instances inherit only the expected behavior from the interface or if it inherits the abstract class. It seems it does the latter and I would like to know an explanation for this and if it is bug Or a feature. :)
This works as expected. I am not entirely sure what is that confuses you.
I needed to know if interface instances inherit only the expected behavior from the interface or if it inherits the abstract class. It seems it does the latter and I would like to know an explanation for this and if it is bug Or a feature. :)
Interfaces don't implement any 'behaviour' (although Java 8 provides default methods) and you can't instantiate one. All those instances you're creating are class instances - in your case, instances of InterfaceImplementer. So let's look at this class and its parent:
TestIntefaceClass implements two interfaces and their methods. Nothing special here.
InterfaceImplementer extends TestIntefaceClass class, it inherits the implementation of sayBye() but it provides its own implementation of sayHi().
Now the following (and the other similar examples from your code)
TestInterfaceOne impl = new InterfaceImplementer();
creates an instance of InterfaceImplementer, as you can see on the right hand side. Thus the implementations that will be used when calling sayHi() and sayBye() will be the ones that Interfaceimplementer overrides / inherits.
LE: This link will probably be useful to you. It discusses using interfaces as types, which is what you're doing.
the "new InterfaceImplementer()" is giving you exactly that ... its just you are decalring them as the various ways .... it's working as expected
Related
I do have a service which needs to handle two types of meal.
#Service
class MealService {
private final List<MealStrategy> strategies;
MealService(…) {
this.strategies = strategies;
}
void handle() {
var foo = …;
var bar = …;
strategies.forEach(s -> s.remove(foo, bar));
}
}
There are two strategies, ‘BurgerStrategy’ and ‘PastaStrategy’. Both implements Strategy interface with one method called remove which takes two parameters.
BurgerStrategy class retrieves meals of enum type burger from the database and iterate over them and perform some operations. Similar stuff does the PastaStrategy.
The question is, does it make sense to call it Strategy and implement it this way or not?
Also, how to handle duplications of the code in those two services, let’s say both share the same private methods. Does it make sense to create a Helper class or something?
does it make sense to call it Strategy and implement it this way or not
I think these classes ‘BurgerStrategy’ and ‘PastaStrategy’ have common behaviour. Strategy pattern is used when you want to inject one strategy and use it. However, you are iterating through all behaviors. You did not set behaviour by getting one strategy and stick with it. So, in my honour opinion, I think it is better to avoid Strategy word here.
So strategy pattern would look like this. I am sorry, I am not Java guy. Let me show via C#. But I've provided comments of how code could look in Java.
This is our abstraction of strategy:
public interface ISoundBehaviour
{
void Make();
}
and its concrete implementation:
public class DogSound : ISoundBehaviour // implements in Java
{
public void Make()
{
Console.WriteLine("Woof");
}
}
public class CatSound : ISoundBehaviour
{
public void Make()
{
Console.WriteLine("Meow");
}
}
And then we stick with one behaviour that can also be replaced:
public class Dog
{
ISoundBehaviour _soundBehaviour;
public Dog(ISoundBehaviour soundBehaviour)
{
_soundBehaviour = soundBehaviour;
}
public void Bark()
{
_soundBehaviour.Make();
}
public void SetAnotherSound(ISoundBehaviour anotherSoundBehaviour)
{
_soundBehaviour = anotherSoundBehaviour;
}
}
how to handle duplications of the code in those two services, let’s say both share the same private methods.
You can create one base, abstract class. So basic idea is to put common logic into some base common class. Then we should create abstract method in abstract class. Why? By doing this, subclasses will have particular logic for concrete case. Let me show an example.
An abstract class which has common behaviour:
public abstract class BaseMeal
{
// I am not Java guy, but if I am not mistaken, in Java,
// if you do not want method to be overriden, you shoud use `final` keyword
public void CommonBehaviourHere()
{
// put here code that can be shared among subclasses to avoid code duplication
}
public abstract void UnCommonBehaviourShouldBeImplementedBySubclass();
}
And its concrete implementations:
public class BurgerSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
public class PastaSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
This is something I ran into trying to solve someone else's question here, in a simplified version. Client and Server with reflexive (circular) dependency use generics to try to keep strongly typed references in super class. The wish was for arbitrary sub-type parings such as ClientType1<->ServerType2 , and for strongly typed calls on specialized methods found only in a specific type.
This only works for one level of depth: from server to client, but fails if you then try to continue from that client back to the server:
Is there any syntax which would allow arbitrary levels of strongly typed calls?
abstract class ServerBase<C extends ClientBase<?>>
{
ArrayList<C> clients = new ArrayList<C>();
}
abstract class ClientBase<S extends ServerBase<?>>
{
S server;
}
class ClientType1<S extends ServerBase<?>> extends ClientBase<S>
{
public void clientType1Method() {}
}
class ServerType1<C extends ClientBase<?>> extends ServerBase<C>
{
}
public class Example {
public static void main(String[] args) {
ServerType1<ClientType1<?>> s = new ServerType1<>();
s.clients.get(0).clientType1Method(); // Single depth level - OK
s.clients.get(0).server.clients.get(0).clientType1Method(); // level 2 - compiler error - undefined method
}
}
In my opinion you should not actually need such an intricate reference.
What you really mean is that the client has to hold a reference to a server it can connect, and viceversa.
what should work is:
abstract class ServerBase<C extends ClientBase<? extends ServerBase>>
{
ArrayList<C> clients = new ArrayList<C>();
}
abstract class ClientBase<S extends ServerBase<? extends ClientBase>>
{
S server;
}
If you do a small tweak with this code it will surely work.
abstract class ClientBase<S extends ServerBase<?>> {
S server;
public abstract void clientMethod();
}
.......
public static void main(String[] args) {
ServerType1<ClientBase<?>> s = new ServerType1<>();
s.clients.get(0).clientMethod(); // Single depth level - OK
s.clients.get(0).server.clients.get(0).clientMethod();
// second level - NO compiler error
}
Well, it fails because you have entered yourself a ? instead of an actual type. If you use
ServerType1<ClientType1<ServerType1<ClientType1<?>>>> s = new ServerType1<>();
s.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).clientType1Method();
instead, it will work. Though it is quite pointless, if we assume that s.clients.get(0).server is the same as s.
Having a circular dependency works only, if you have named types you can refer to, e.g.
public static <S extends ServerType1<ClientType1<S>>> void main(String[] args) {
ServerType1<ClientType1<S>> s = new ServerType1<>();
s.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0)
.server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0)
.server.clients.get(0).server.clients.get(0).clientType1Method();
}
Though this is likely to be impractical for most use cases. As soon as you end up having to instantiate S, you would need a real class instead. You should rethink whether you really need such a generic construct. And if you really consider creating such code with helper type variables that are irrelevant to the method’s caller, you should do that with private methods, to avoid them being visible in the public API of your class.
Consider:
public class test01{
public void doSomething(){
// do something
}
}
public class test02{
public void printSomething(){
// print something
}
}
// in main
test01 t1 = new test01();
test02 t2 = new test02();
// I want do to something like this
test01 t3 = t1.merge(t2);
// with t3 I should be able to access both t1 and t2 functions
t3.doSomething();
t3.printSomething();
Please let me know if this is possible in Java? If yes, then let me know how can I achieve this?
There is no multiple inheritance in java. What you can do is making test02 a subclass of test01 then create test03 as a subclass of test02.
OR
you can compose them into a Test03 class like this:
public class Test03 {
private Test01 test01;
private Test02 test02;
public void doSomething() {
test01.doSomething();
}
public void printSomething() {
test02.printSomething();
}
}
Please note that in java you shouldn't use class names like test01. They should be meaningful and comform to the java class naming guidelines.
Your best option is probably this:
public class TestSet {
private test01 t1 = new test01();
private test02 t2 = new test02();
public void doSomething() {
t1.doSomething();
}
public void printSomething() {
t2.printSomething();
}
}
In some languages, multiple inheritance is supported, which may be what you're looking for here. But not in Java. You may or may not want to make a couple of interfaces here to tie TestSet more closely together with test01 and test02.
Please let me know if this is possible in Java?
It is not possible. You cannot combine behaviour dynamically like that in Java.
The normal way to combine behaviour in Java is to use some combination of inheritance and wrappering or delegation. Even then, there will be an issue of subtyping ... unless you use interfaces ... because Java does not allow a class to have multiple (direct) superclasses.
Consider for #Panzercrisis's example. While his test03 class implements methods with the same signatures as the test01 and test02 classes, an instance of test03 is not type compatible with either of them. (You can't use a test03 instance as a test01 or a test02. Java doesn't support duck typing!)
To address that you would need to define interfaces face01 and face02 that are implemented by test01 and test02 respectively. Then you would implement test03 as implementing both face01 and face02.
But this is all static classes and static typing.
Under some circumstances, you could use DynamicProxy or something similar to "synthesize" a class that "merges" the behaviour of two existing classes. However, that is all done with static types and code generation behind the scenes. Moreover, this approach would only viable if you'd had the foresight to define a bunch of interfaces (e.g. face01 and face02) and write your application code against the interfaces rather than the implementation classes.
You can define a class Y in another class X as inner class and you can use class Y in class X. Other than that, as I know there is no way to do that.
Short answer, no it's not possible how you describe.
The appearance of doing this might be possible if test01 and test02 where interfaces and you had a third class test03 implement both. In C++ this would be done by multiple inheritance but that would function much the same way (i.e. you would have to create a third class that instead extends both) and this option isn't available in Java anyway.
Another option would be some sort of composition such as #Panzercrisis describes.
The final option (I can think of) would be to have test02 extend test01 but that alters test02.
But generally, no, not possible.
No you can't, really do this in way how you describe this,
you can do
public class test01 extend test02{ ....
}
so your test1, you can use methods from both classes,
but if you can really whant yo play with merging classes together, you can do some abomination like this one:
public class MyObject {
Map<String, Object> objects = new HashMap<String, Object>();
Map<String, Method> methods = new HashMap<String, Method>();
public Object execute(String methodAName)
{
Object object = objects.get(methodAName);
Method method = methods.get(methodAName);
if (object==null || method==null)
{
throw new RuntimeException("method not found");
}
try {
return method.invoke(object, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void merge(Object o) {
for (Method m : o.getClass().getMethods()) {
objects.put(m.getName(), o);
methods.put(m.getName(), m);
}
}
}
and when you can use it like that
MyObject o = new MyObject();
o.merge(new test01());
o.merge(new test02());
o.execute("printSomething");
o.execute("doSomething");
but as i said, not recommended
You can do something similar using Java inheritance, But not the same thing. you can use extends here. But you have to make sure method overriding not happen else your requirement not match.
Test02 extends Test01
Then
Test03 extends Test02
Now you can achieve some thing similar.
Test03 test=new Test03();
test.callMethodInTest1();
test.callMethodInTest2();
Sample:
public class Test1 {
public String callMethodInTest1() {
return "test1";
}
}
.
public class Test2 extends Test1{
public String callMethodInTest2() {
return "test2";
}
}
.
public class Test03 extends Test2 {
public static void main(String[] args){
Test03 sample=new Test03();
sample.callMethodInTest1();
sample.callMethodInTest2();
}
}
Here is code:
IDefaultInterface.aj:
public interface IDefaultInterface {
public void m1();
static aspect Impl{
public int f1;
public void IDefaultInterface.m1(){
}
}
}
DefaulstInterfaceClass.java:
public class DefaultInterfaceClass implements IDefaultInterface {
#Override
public void m1() {
}
void mm() {
f1 = 9;
}
}
In the second piece of code I'm trying to override m1() method and access f1 field. The compiler allows neither one.
How to overcome these limitations?
Additional thoughts. I would not wonder so much if in "AspectJ in action" 2 edition wasn't said about using this idiom that effect should be the same "as extending the default implementation for both (if multiple inheritance was allowed in Java)." I believe that multiple inheritance associated with C++ for majority. So, why not provide the semantics to which people used to?
I'm not fluent in AspectJ, but I see a couple of questionable things: your aspect is trying to define a non-abstract method in an interface, and your class is trying to access field f1 as if it owns the field, when you've declared f1 on the aspect. I'm not quite sure what you're trying to do here, but I don't think you're going about it in the right way.
First of all I misspelled f1 declaration. It should be
public int IDefaultInterface.f1;
It solves access field problem.
The second problem is solved by using following code:
public interface IDefaultInterface {
public void m1();
public static interface Impl extends IDefaultInterface{
static aspect Implementation{
public int IDefaultInterface.Impl.f1;
public void IDefaultInterface.Impl.m1(){
}
}
}
}
And then:
public class DefaultInterfaceClass implements IDefaultInterface.Impl ....
I know that an interface must be public. However, I don't want that.
I want my implemented methods to only be accessible from their own package, so I want my implemented methods to be protected.
The problem is I can't make the interface or the implemented methods protected.
What is a work around? Is there a design pattern that pertains to this problem?
From the Java guide, an abstract class wouldn't do the job either.
read this.
"The public access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, your interface will be accessible only to classes defined in the same package as the interface."
Is that what you want?
You class can use package protection and still implement an interface:
class Foo implements Runnable
{
public void run()
{
}
}
If you want some methods to be protected / package and others not, it sounds like your classes have more than one responsibility, and should be split into multiple.
Edit after reading comments to this and other responses:
If your are somehow thinking that the visibility of a method affects the ability to invoke that method, think again. Without going to extremes, you cannot prevent someone from using reflection to identify your class' methods and invoke them. However, this is a non-issue: unless someone is trying to crack your code, they're not going to invoke random methods.
Instead, think of private / protected methods as defining a contract for subclasses, and use interfaces to define the contract with the outside world.
Oh, and to the person who decided my example should use K&R bracing: if it's specified in the Terms of Service, sure. Otherwise, can't you find anything better to do with your time?
When I have butted up against this I use a package accessible inner or nested class to implement the interface, pushing the implemented method out of the public class.
Usually it's because I have a class with a specific public API which must implement something else to get it's job done (quite often because the something else was a callback disguised as an interface <grin>) - this happens a lot with things like Comparable. I don't want the public API polluted with the (forced public) interface implementation.
Hope this helps.
Also, if you truly want the methods accessed only by the package, you don't want the protected scope specifier, you want the default (omitted) scope specifier. Using protected will, of course, allow subclasses to see the methods.
BTW, I think that the reason interface methods are inferred to be public is because it is very much the exception to have an interface which is only implemented by classes in the same package; they are very much most often invoked by something in another package, which means they need to be public.
This question is based on a wrong statement:
I know that an interface must be public
Not really, you can have interfaces with default access modifier.
The problem is I can't make the interface or the implemented methods protected
Here it is:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Hence, achieving what you wanted, prevent interface and class usage outside of the package.
Here's how it could be done using abstract classes.
The only inconvenient is that it makes you "subclass".
As per the java guide, you should follow that advice "most" of the times, but I think in this situation it will be ok.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Here's another solution, inspired by the C++ Pimpl idiom.
If you want to implement an interface, but don't want that implementation to be public, you can create a composed object of an anonymous inner class that implements the interface.
Here's an example. Let's say you have this interface:
public interface Iface {
public void doSomething();
}
You create an object of the Iface type, and put your implementation in there:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
Whenever you need to invoke doSomething(), you invoke it on your composed impl object.
I just came across this trying to build a protected method with the intention of it only being used in a test case. I wanted to delete test data that I had stuffed into a DB table. In any case I was inspired by #Karl Giesing's post. Unfortunately it did not work. I did figure a way to make it work using a protected inner class.
The interface:
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
Then the inner class defined as protected in public class:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
You can then access the protected method only from other classes in the same package, as my test code was as show:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
A little late for the original poster, but hey, I just found it. :D
You can go with encapsulation instead of inheritance.
That is, create your class (which won't inherit anything) and in it, have an instance of the object you want to extend.
Then you can expose only what you want.
The obvious disadvantage of this is that you must explicitly pass-through methods for everything you want exposed. And it won't be a subclass...
I would just create an abstract class. There is no harm in it.
With an interface you want to define methods that can be exposed by a variety of implementing classes.
Having an interface with protected methods just wouldn't serve that purpose.
I am guessing your problem can be solved by redesigning your class hierarchy.
One way to get around this is (depending on the situation) to just make an anonymous inner class that implements the interface that has protected or private scope. For example:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
Then in the user of Foo:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
#Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
This saves you from having the following:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
#Override public void hiddenMethod() { ... }
}
I think u can use it now with Java 9 release. From the openJdk notes for Java 9,
Support for private methods in interfaces was briefly in consideration
for inclusion in Java SE 8 as part of the effort to add support for
Lambda Expressions, but was withdrawn to enable better focus on higher
priority tasks for Java SE 8. It is now proposed that support for
private interface methods be undertaken thereby enabling non abstract
methods of an interface to share code between them.
refer https://bugs.openjdk.java.net/browse/JDK-8071453