Here's the situation: I have a class and I create instances of. I'd like it to inherit the majority of the methods/variables in the class, but I want a few methods to be required to be overridden, similar to how an abstract class works.
Here is my code so far.
public class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public void methodThree() {
//Override Me
}
}
I can't [make the class abstract] because I need to create instances
Making the class abstract does prevent instantiation, but since you want to prevent instantiation unless a method is overridden, this is the right thing to do.
You can make overrides anonymously, so syntactically this would be similar to instantiating the base class:
public abstract class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
...
static void main(String[] args) {
Example e = new Example() {
#Override
public void methodThree() {
... // Do something
}
};
}
First of all, requiring people to write code in a particular way can be counter productive. Someone may have a legitimate use-case (that you had not considered !!) for dong it differently, and your restriction may force them to solve the problem in a way that makes things significantly worse than if your restriction wasn't there. Bear this in mind ...
But here's a solution:
public abstract class ExampleBase {
public void methodOne() {
// Inherited
}
public void methodTwo() {
// Interited
// Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
public final class Example {
#Override
public void methodThree() {
// Do stuff.
}
}
We have solved the problem by moving all of the members that you want to inherit to an abstract superclass. Any methods that you want to force people to override are declared as abstract. By declaring your concrete Example class as final, we prevent them from circumventing your requirement and subclassing Example without overriding methodThree.
Related
I have interface:
public interface Doable {
void doSomething();
}
and the class that implements it:
public class DoJump() implements Doable {
#Override
private void doSomething() {
fireJumpHandler();
}
}
This is stupid example, but I would like to present the problem.
This code doesn't compile, I am getting an error in Eclipse IDE:
Cannot reduce the visibility of the inherited method from
Doable
I have common interface that declares a method. This method is overriden in concrete class. I would like to avoid another class that can extend this class (DoJump), so I would like to hide this method from sub classes. I would like to use private modifier, but Java does not allow me to do it.
Why it is impossible, and how to workaround it?
I'd like to answer your last question "How to workaround it?" as this is not described in the related question. Create a second interface NotDoable which simply does not have doSomething() declared. Then let your DoJump implement both interfaces. Give everyone that shouldn't override doSomething a reference to the interface NotDoable instead of the true type DoJump. Then they won't know that the object truly can doSomething, they won't know per class design. Of course, one can workaround this but one actually can workaround everything. The class design is more correct this way. Here's some code:
public interface Doable {
public void doSomething();
}
public interface NotDoable {
}
public class DoJump implements Doable, NotDoable {
#Override
public void doSomething() {
System.out.println("hi");
}
public NotDoable meAsNotDoable() {
return this;
}
public static void main(String[] args) {
DoJump object = new DoJump();
// This call is possible, no errors
object.doSomething();
NotDoable hidden = object.meAsNotDoable();
// Not possible, compile error, the true type is hidden!
hidden.doSomething();
}
}
But as said, one can workaround this by using if (hidden instanceof DoJump) { DoJump trueObject = (DoJump) hidden; }. But well, one can also access private values via reflection.
Other classes now implement NotDoable instead of extending DoJump. If you declare everything others should know about DoJump in this interface, then they only can do what they should do. You may call this interface IDoJump and the implementing class DoJump, a common pattern.
Now the same a bit more concrete.
public interface IDog {
public void bark();
}
public interface ICanFly {
public void fly();
}
public class FlyingDog implements IDog, ICanFly {
#Override
public void bark() {
System.out.println("wuff");
}
#Override
public void fly() {
System.out.println("Whuiiii");
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
// Both works
flyingDog.fly();
flyingDog.bark();
IDog dog = (IDog) flyingDog;
// Same object but does not work, compile error
dog.fly();
ICanFly canFly = (ICanFly) flyingDog;
// Same object but does not work, compile error
canFly.bark();
}
}
And now an extending class.
public class LoudDog implements IDog {
#Override
public void bark() {
System.out.println("WUUUUFF");
}
// Does not work, compile error as IDog does not declare this method
#Override
public void fly() {
System.out.println("I wanna fly :(");
}
}
In the end, be aware that if others know that their IDog actually is a FlyingDog (and they cast it), then they must be able to call fly() as a FlyingDog must can fly. Furthermore, they must be able to override the behavior as long as they follow the specification of fly() given by its method-signature. Imagine a subclass called PoorFlyingDog, he needs to override the default behavior, else he can perfectly fly, but he is a poor flyer.
Summarized: Hide to others that you're actually a DoJump, also hide that you are a Doable, pretend to only be a NotDoable. Or with the animals, pretend to only be an IDog instead of a FlyingDog or ICanFly. If the others don't cheat (casting), they won't be able to use fly() on you, though you actually can fly.
Add final to DoJump declaration to prevent this class to be overriden (and therefore doSomething() to be overriden too).
public final class DoJump implements Doable {
#Override
public void doSomething() {
fireJumpHandler();
}
}
If you still need to be able to inherit DoJump but you don't want doSomething() to be overriden, put the final modifier in the method signature
public class DoJump implements Doable {
#Override
public final void doSomething() {
fireJumpHandler();
}
}
I am not sure how am I suppose to go about my question. It is about Android can Instantiate Interface. I am trying to do in C#. Now I am pretty sure that the rules for both Java and C# is you can't create an Instance of abstract and Interface as being said.
But I would really like to know how Android does this practice.
In Android you can do this.
public interface Checkme{
void Test();
void Test2();
}
public void myFunc(Checkme my){
//do something
}
// Now this is the actual usage.
public void Start(){
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
}
Actually once you press Enter on new Checkme() You will automatically get the Override methods of the Interface. Like auto Implement method of an Interface in C#.
I hope my question make sense.
C# doesn't support anonymously auto-implemented interfaces because it has delegates:
public void Foo(Func<string> func, Action action) {}
// call it somewhere:
instance.Foo(() => "hello world", () => Console.WriteLine("hello world"));
With delegates you can fill the gap and it can be even more powerful than implementing interfaces with anonymous classes.
Learn more about delegates.
This is an Anonymous Class:
public void Start(){
myFunc(new Checkme() {
#Override
public void Test() {
}
#Override
public void Test2() {
}
});
}
An anonymous class is an unnamed class implemented inline.
You could also have done it using a Local Class, but those are rarely seen in the wild.
public void Start(){
class LocalCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
myFunc(new LocalCheckme());
}
These both have the advantage that they can use method parameters and variables directly, as long as they are (effectively) final.
As a third option, you could do it with an Inner Class.
private class InnerCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
public void Start(){
myFunc(new InnerCheckme());
}
An inner class cannot access method variables (obviously because it's outside the method), but can be used by multiple methods.
Any local values from the method can however be passed into the constructor and stored as fields of the inner class, to get the same behavior. Just requires a bit more code.
If the inner class doesn't need access to fields of the outer class, it can be declared static, making it a Static Nested Class.
So, all 3 ways above a very similar. The first two are just Java shorthands for the third, i.e. syntactic sugar implemented by the compiler.
C# can do the third one, so just do it that way for C#.
Of course, if the interface only has one method, using a Java lambda or C# delegate is much easier than Anonymous / Local / Inner classes.
If I understand correcly, you're defining a class that implements an interface, and when you specify that the class implements an interface, you want it to automatically add the interface's methods and properties.
If you've declared this:
public interface ISomeInterface
{
void DoSomething();
}
And then you add a class:
public class MyClass : ISomeInterface // <-- right-click
{
}
Right-click on the interface and Visual Studio will give you an option to implement the interface, and it will add all the interface's members to the class.
you mean something like this?
pulic interface Foo{
void DoSomething();
}
public class Bar : Foo {
public void DoSomething () {
//logic here
}
}
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
You're passing into myFunc() something that is called an anonymous class. When it says "new Checkme() { .... }", it is defining an anonymous implementation of the Checkme interface. So, it's not an instance of the interface itself, just an instance of a type that implements it.
In C# anonymously implemented classes for Interface are not auto generated just like in java, you need to follow the below procedure to workout.
public class MyClass {
public void someMethod (string id, IMyInterface _iMyInterface) {
string someResponse = "RESPONSE FOR " + id;
_iMyInterface.InterfaceResponse (someResponse);
}
}
public interface IMyInterface {
void InterfaceResponse (object data);
void InterfaceResponse2 (object data, string x);
}
public class MyInterfaceImplementor : IMyInterface {
private readonly Action<object> actionname;
private readonly Action<object, string> actionInterfaceResponse2;
public MyInterfaceImplementor (Action<object> InterfaceResponse) {
this.actionname = InterfaceResponse;
}
public MyInterfaceImplementor(Action<object> interfaceResponseMethod, Action<object, string> interfaceResponseMethod1) {
this.actionname = interfaceResponseMethod ?? throw new ArgumentNullException(nameof(interfaceResponseMethod));
this.actionInterfaceResponse2 = interfaceResponseMethod1 ?? throw new ArgumentNullException(nameof(interfaceResponseMethod1));
}
public void InterfaceResponse (object data) {
this.actionname (data);
}
public void InterfaceResponse2(object data, string x) {
this.actionInterfaceResponse2(data, x);
}
}
Gist Source : https://gist.github.com/pishangujeniya/4398db8b9374b081b0670ce746f34cbc
Reference :
I would like to prevent a class from calling its own method. The method shall only be callable by its super class.
Right now, I cannot think of any way to achieve this (cleanly). But maybe someone knows a solution?
In code:
public abstract class A {
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
public class B extends A {
#Override
protected void foo() {
//do smth
}
private void barB() {
//must not be able to call foo() here
}
}
Edit: the explanation why I would like to do this:
A is lets say a vehicle. B can be a car or an airplane. The method foo() would be startEngines(). -> I want to make sure that the engines can only be started by calling the method barA().... does that make any sense?
There is a way to do it, but you need to use Google Error Prone. This is an extension of the Java compiler that aims to provide more and more helpful warnings and errors (similar to FindBugs and PMD, but with less false alarms). I can only recommend it, it has already helped us to find some bugs.
Specifically, it contains an annotation #ForOverride and an according compile-time check. This annotation is meant to be used for protected methods that the sub-class and any other class should not call, but only the defining class.
So using
public abstract class A {
#ForOverride
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
would exactly achieve what you want.
You can integrate Error Prone into most build systems like Maven and Ant. Of course, it won't help if somebody compiles your source without Error Prone (for example in Eclipse), but using it in a continous-integration system would still allow you to find such issues. The source code still stays compatible with regular Java compilers (provided you have error_prone_annotations.jar on the class path), other compilers will simply not do the additional checks.
this answer has a good hint.
add below method in your class (class B):
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - 1 - depth].getMethodName();
}
and change the foo method in class B to this:
#Override
protected void foo() {
//....
if (getMethodName(0)=="barB"){
// tell you are not able to call barB
}
}
Considering your vehicle and engine scenario, I think you need to reconsider your design a bit.
Your vehicle could be a car, aeroplane, etc but car, aeroplane, ... each have separate engines and therefore different startEngine method. So declare your class vehicle as abstract like you did and class startEngine as abstract method . Next , subclass Vehicle and implement startEngine in them , now you can invoke startEngine on the subclass instances
abstract class Vehicle{
abstract void startEngine();
}
public class Car extends Vehicle{
public void startEngine(){
//implementation
}
public static void main(String[] arg){
Vehicle v=new Car();
v.startEngine();
}
}
Add Anonymouse inner class to barA method via Interface, so you will need to implement a method for foo() (functional interface). It won't be part of Class B.
you could put an interface as a member in the super class given to it via the constructor. the child class implements the method but can't call it except by making it static.
interface Foo {
void stopEngines();
void startEngines();
}
abstract class Base {
final private Foo foo;
public Base(final Foo foo) {
this.foo = foo;
}
private void barA() {
// do smth
foo.startEngines();
}
}
class Child extends Base {
public Child() {
super(new Foo() {
boolean engineRunning;
#Override
public void stopEngines() {
this.engineRunning = false;
}
#Override
public void startEngines() {
this.engineRunning = true;
}
});
}
private void barB() {
// can't call startEngines() or stopEngines() here
}
}
class Child2 extends Base {
public Child2() {
super(new Foo() {
#Override
public void stopEngines() {
stopEngines();
}
#Override
public void startEngines() {
startEngines();
}
});
}
static void stopEngines() {
// influence some static state?
}
static void startEngines() {
// influence some static state?
}
private void barB() {
// can call stopEngines() and startEngines(), but at least they have to be static
}
}
Of course, this is not really what you asked for, but about as much as you can do about it in Java, I guess.
Seeing the startEngines explanation, this solution might even suffice.
I guess you wouldn't care about the class calling its static methods, since they can only influence a static state, which is used seldom. The methods within the anonymous interface implementation can mutually call each other, but I guess that would be OK, since you only seem to be trying to prevent others to start the engines in some different way.
I guess this is similar to the problem AWT/Swing has with overriding the paint(Graphics g) method on a component (or onCreate(..) in Android Activities). Here you are overriding the paint method but you should never call it.
I think the best thing you can do is add documentation to the method to clarify that it should never be explicitly called by the subclasses OR re-evaluate your design.
I have a simple design question. I am not sure how to design the following "situation" with respect to scalability and object-orientation.
interface IA {
void update();
}
class A implements IA {
public void update(){
updateInX();
updateInY();
}
private void updateInX(){
...
}
private void updateInX(){
...
}
}
The redundancy (updateInX(), updateInY()) seems like a bad design, but I have no idea how to improve it. I would appreciate your help!
This problem can be solved using Template method design pattern. You will basically define abstract class which contains abstract methods which has to be overriden and leave the computation itself on the abstract class. For instance
public abstract class Something {
public void update(){
updateInX();
updateInY();
printResult();
}
private void printResult() {
//print
}
protected abstract void updateInX();
protected abstract void updateInX();
}
This will make a child object implement only necessary methods and leave the computation on the base class.
I am trying to wrap my mind around something in java. When I pass an object to another class' method, can I not just call any methods inherent to that object class?
What is the reason code such as the example below does not compile?
Thank you,
class a {
public static void myMethod(Object myObj) {
myObj.testing();
}
}
class b {
public void testing() {
System.out.println ("TESTING!!!");
}
}
class c {
public static void main (String[] args) {
b myB = new b();
a.myMethod(myB);
}
}
Edit: The reason I have left the parameter in myMethod as type Object, is because I would like to be able to pass in a variety of object types, each having a testing() method.
If you would like to pass in a variety of objects with testing() methods, have each object implement a Testable interface:
public interface Testable
{
public void testing()
}
Then have myMethod() take a Testable.
public static void myMethod(Testable testable)
{
testable.testing();
}
Edit: To clarify, implementing an interface means that the class is guaranteed to have the method, but the method can do whatever it wants. So I could have two classes whose testing() methods do different things.
public class AClass implements Testable
{
public void testing()
{
System.out.println("Hello world");
}
}
public class BClass implements Testable
{
public void testing()
{
System.out.println("Hello underworld");
}
}
The problem is that myMethod can't know it's getting a b object until it actually runs. You could pass a String in, for all it knows.
Change it to
public static void myMethod(b myObj) {
myObj.testing();
}
and it should work.
Update of the question:
Edit: The reason I have left the parameter in myMethod as type Object, is because I would like to be able to pass in a variety of object types, each having a testing() method.
As Amanda S and several others have said, this is a perfect case for an interface. The way to do this is to create an interface which defines the testing() method and change myMethod to take objects implementing that interface.
An alternative solution (without interfaces) would be to reflectively discover if the object has a testing() method and call it, but this is not recommended and not needed for a such a simple case.
What you are talking about is duck typing. Java doesn't have duck typing.
Therefore you need to define an interface that all the classes with a testing() method implement.
e.g:
public interface Testable
{
public void testing()
}
class B implements Testable
{
public void testing() {
System.out.println ("TESTING!!!");
}
}
class A {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
Your issue is a classic argument in favor of an interface. You want as generic as possible, yet you want every object you pass to have a testing() method. I suggest something along the lines of the following:
public interface Testable
{
public void testing();
}
public class A
{
public static void myMethod(Testable myObj)
{
myObj.testing();
}
}
public class B implements Testable
{
public void testing()
{
System.out.println("This is class B");
}
}
public class C implements Testable
{
public void testing()
{
System.out.println("This is class C");
}
}
public class Test
{
public static void main (String[] args)
{
B myB = new B();
C myC = new C();
A.myMethod(myB); // "This is class B"
A.myMethod(myC); // "This is class C"
}
}
Because you're passing in an Object (b inherit from Object). Object doesn't have testing, b does.
You can either pass in b or cast the object to b before calling the method.
EDIT
To pass in a generic class that implements that method: you'll want to make an interface that has the method signature and pass in the interface type instead of Object. All objects that you pass in must implement the interface.
You can only access the members that are visible for the type of reference you have to the object.
In the case of myMethod(Object myObj) that means only the members defined in Object, so in class a the members of class b will not be visible.
If you changed the definition of a.myMethod to be public static void myMethod(b myObj) you would then be able to see the testing method on the instance of b while in myMethod.
update based on clarification:
In that case defining an interface for all of them to implement is likely what you want.
public interface Testable {
public void testing();
}
public class a {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
public class b implements Testable {
public void testing () {
System.out.println("TESTING!!!");
}
}
Why can’t java find my method?
Because of the way Java was designed.
Java is "statically typed" that means objects types are checked during compilation.
In Java you can invoke a method only if that method belongs to that type.
Since this verification is made during compilation and the Object type does not have the "testing()" method, the compilation fails ( even though if at runtime the objects do have that method". This is primarily for safety.
The workaround as described by others will require you to create a new type, where you can tell the compiler
"Hey, the instances of this type will respond the the testing method"
If you want to pass a variety of objects and keep it very generic, one way is having those objects to implement and interface.
public interface Testable {
public void testing();
}
class A implements Testable { // here this class commits to respond to "testing" message
public void testing() {
}
}
class B implements Testable { // B "is" testable
public void testing() {
System.out.println("Testing from b");
}
}
class C implements Testable { // C is... etc.
public void testing() {
//....
}
}
Later somewhere else
public void doTest( Testable object ) {
object.testing();
}
doTest( new A() );
doTest( new B() );
doTest( new C() );
The "OTHER" way to do this, in java is invoking the methods reflectively, but I'm not sure if that's what you need, for the code is much more abstract when you do it that way, but that's how automated testing frameworks (and a lot of other frameworks such as Hibernate) do actually work.
I hope this help you to clarify the reason.
If you REALLY, REALLY want to keep the parameter as abstract as possible, you should consider reflection API. That way, you can pass whatever object you want and dynamically execute the method you want. You can take a look at some examples.
It's not the only way, but it might be a valid alternative depending on your problem.
Keep in mind that reflection is way slower than calling your methods directly. You might consider using an interface as well, such as the one on Amanda's post.