The title is not quite clear, but I didn't see how to explain it in a short sentence.
I have an interface myInterface (This must be an interface, not an abstract, because enum will implement it).
I expect to have an attribute myAttribute (integer) which is not reachable from outside, except for the derivated classes from the interface (protected).
I want a method myMethod that contans myInterface as input parameter. But then, I have trouble when I try to implement it.
The method looks like this
boolean myMethod(myInterface interface)
{
return this.myAttribute>interface.myAttribute;
}
I can't define "myAttribute" as protected in "myInterface".
If I don't define "myAttribute" in "myInterface", I can't use it in the definition of myMethod, when I implement it in my derivated class : The signature should contain "myInterface" as input parameter, and this one doesn't have any "myAttribute" attribute.
The only solution I have now is to cast "myInterface" in its derivate, but I don't like it (Globally, I don't like casts). Does anyone has another idea?
You cannot.
Interfaces can only define (implicitly) public static final variables, otherwise said, public constants.
What you should do is define a method returning your attribute in your interface, which in turn, its implementing classes will be forced to implement (if they're not abstract).
The method will be implicitly public.
This will also enforce the encapsulation of the variable within the implementing classes.
You can then retrieve the value by virtually invoking the getter method on the interface: myInterface.getMyAttribute().
Edit
If your scope is to not be able to access the value an instance field outside classes that implement a common interface at all, you can proxy you hierarchy by having an abstract class in between the interface and your implementing classes.
In turn, the abstract class would implement none of the interface methods (hence still forcing the concrete classes to implement all), but instead feature a protected attribute that the concrete classes would all have access to.
Finally the concrete classes could decide whether or not to let other classes access that field.
Related
I've created an abstract class contains a method with an implementation. This method is called by subclasses to populate a list, which should be shared amongst all instances of each individual subclass (like an abstract static field which is different and static to each subclass). The issue is: abstract static fields do not exist, so how else might I be able to achieve this behaviour?
For context, the implemented method on the abstract class is for resolving classes from an unqualified name via the reflections8 package. This method calls an abstract method to get the packages to reflect, which just returns a String[] (as subclasses will want to search in different packages). This method then generates a Map<String, Class<?>> containing a mapping of the name of each reflected class to the Class, which is what I would like to share between instances of each specific subclass type (so that it doesn't have to reflect for the same subclass more than once). Ultimately, this method is called by the subclass in order to instantiate a class from its unqualified name.
Please forgive me if this is a rather strange way of doing things; I come from the land of iOS where we don't have package names attached to class names (so I can just call NSClassFromString("ClassName") and that's it).
EDIT: Check out this gist for the current implementation (and check out the comment for a usage example).
My thoughts: if you're wanting your subclasses to have their own respective static fields, it's best to just have those static fields declared in them rather than this abstract class.
From what I understand, your abstract class is really just a placeholder for this one implemented method. Do any of your subclasses override anything from the parent? If not, maybe it doesn't need to be an abstract class.
Plus, does your abstract class need any state? Because if not, you might be better off with this: change your abstract class to be a static class, and your implemented method be a static method, which accepts an "ClassName" argument. Then in your subclasses you can just directly call the method with your subclass' static fields using something akin to MyStaticClass. NSClassFromString(subclassStaticField);
There is no equivalent for abstract static for fields:
An instance field cannot be abstract. It really makes no sense. abstract means we are deferring some of the details to a subclass. But for an instance field there is nothing that it makes sense to defer.
A static field is not inherited anyway, so there is no way one could be used polymorphically. static fields with the same name in different classes are distinct variables.
You can (of course) use reflection to test if a field (static or instance) has been declared ... but that's not what abstract means in Java.
Solution:
If you want an instance field to exist in all of the subclasses of an abstract class, declare it as a regular field in the abstract class.
If you want a static field to exist in all subclasses, you have no choice but to explicitly declare it in each subclass. You won't be able to use it / them polymorphically.
I am creating an interface with many implementing classes and there is an attribute they must all have;
I guess it's better to put that attribute in their interface than writing many constructor lines, but attributes can only be static final and require to be immediately initialized.
public interface Interface{
static final AttrType attribute = new AttrType( *something* );
I have 2 problems: this attribute is a class and its constructor needs some other type parameters not just ints, and also it shouldn't be initialized here, I need all implementing classes of the interface to work on the same instance of AttrType which as i said I won't instantiate in the interface.
So, as I am not expert enough, is there a way to do this in the interface or I should just write a line in every subclass' constructor to put in the one AttrType instance they need?
Java interfaces describe what a class can do, rather than what a class is. Therefore, an interface only describes methods.
You could handle this in a few ways:
Using an interface, you could have a getter for the variable, which would force the implementing classes to have the variable. Something like "public AttrType getAttribute();"
Or you could create a class, probably abstract, which implements the interface and has the variable, and its getter and setter. The subclasses all would inherit this variable and behavior.
Would it be possible to add also a common base class to go with your common interface which all the classes could inherit? Then the common base class constructor could contain the attribute instance. Also you could consider using an abstract class instead of interface.
How to make a class only extendable not directly usable and with a different implementation for the method by every sub class? I thought about interfaces but interfaces doesn't obligate me to initialize variables just obligates me to implement the methods I want something that obligates every single sub class to initialize a some specific variables they extend.
Add the abstract modifier. That is
public abstract class MyClass { ... }
As he said what you want is an Abstract Class, an abstract class is like a template:
Thi is what Oracle say:
Abstract Classes Compared to Interfaces
Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods. With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.
Which should you use, abstract classes or interfaces?
Consider using abstract classes if any of these statements apply to your situation:
You want to share code among several closely related classes.
You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
Consider using interfaces if any of these statements apply to your situation:
You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.
You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
You want to take advantage of multiple inheritance of type.
Here is more information
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
and you can use as he said
abstract class Name{}
I want to declare a couple of abstract methods (so the implementation is required in the classes that inherit from this one) to fit my situation, which is:
I am making a puzzles solver program. So far I have 3 packages:
games.puzzles
games.puzzles.rivercrossing
games.puzzles.rivercrossing.wolfgoatcabbage
I don't want to get too specific but in the games.puzzles.rivercrossing package I have two classes that represent a bank and a state: GenericBank and GenericState.
Now, they define some behavior, but there are some methods that the classes that inherit from these must have, like move() to move one element from one bank to the other or isPermitted() and isFinal() to check the states.
For example, in the last package I have the WolfGoatCabbageGame class and it must have its own Bank and State classes which will inherit from the generic ones. These particular Bank and State classes must implement the methods I mentioned above, for example in the Wolf, Goat and Cabbage game, to check if the goat and the wolf are not in the same bank, etc.
So initially I declared the generic classes as abstract, and these methods to be implemented abstract as well:
public abstract class GenericBank {
// more members ...
public abstract boolean move(Element element, GenericBank dst);
// more members...
}
public abstract class GenericState {
// more members...
public abstract boolean isPermitted(GenericBank bank);
public abstract boolean isFinal(GenericBank bank);
// more members...
}
And this looked like it'd work until I found out I had to instantiate GenericBank and GenericState objects, which of course can't be done if these classes are abstract.
So I had to remove the abstract qualifier from the classes.
So... what can I do? How can I declare abstract methods (or achieve the same behavior) in a non-abstract class?
How to declare abstract method in non-abstract class?
Answer: You can't. It's kind of the definition of abstract. It's the same reason you can't instantiate an object as an abstract class.
Either:
A) You need to use Interfaces
B) Leave the methods empty in the parent class:
//technically this needs to return a value, but it doesn't need to *do* anything
public boolean isPermitted(GenericBank bank){ return false; }
C) Refactor your code so that you aren't instantiating abstract objects. I cannot advise how to do this as you haven't provided any code regarding this.
You could replace the abstract methods with empty methods that do nothing and return the default value of their respective return type (and, if necessary, make it part of the generic classes contract, that subclasses must override these methods).
Alternatively, you could keep your abstract Generic*-classes and add Null*-classes with abovementioned empty implementations, following the Null object pattern.
You cannot declare abstract methods in a non-abstract class, final dot.
That would simply defile the concept of abstract methods.
What you can do is have your class hierarchy implement interfaces dictating the required methods to implement.
If you found your formerly abstract classes were actually better designed as concrete classes, do convert them to concrete classes and implement the methods, even with a default, general implementation.
You can then fine-tune the overrides in your child classes.
Remove the abstract qualifier and add a empty body, or throwing some runtime exception.
Or instantiate these generic classes as anonymous sub classes
You cannot, the very definition of an abstract class is that it has abstract methods.
What you can do, is define default behaviour, that can be overruled by subclasses.
However, I would carefully consider your class hierarchy before doing this. The fact that you need to instantiate some classes before their actual implementations are known, suggests that your design may need re-thinking.
If you're going to re-design, you will want to look at the time of instantiation - and underlying that, the reasons for instantiating.
Right now, you want to use some of the common behaviour of a class, before the actual instance of that class is known.
It goes a bit beyond the scope of answering the question, but: consider explaining the design of the code to a friend. Or to a rubber duck. This may help you to find a fresh approach.
You can use Virtual instead!
internal class ClassA
{
public void Print()
{
Console.WriteLine("A");
PrintVirtual();
Console.WriteLine("--------------------------------------------------");
}
protected virtual void PrintVirtual()
{
Console.WriteLine("Virtual");
}
}
internal class ClassB : ClassA
{
protected override void PrintVirtual()
{
Console.WriteLine("B");
}
}
internal class ClassC : ClassA
{
protected override void PrintVirtual()
{
Console.WriteLine("C");
base.PrintVirtual();
}
}
and you can run the test
new ClassA().Print();
new ClassB().Print();
new ClassC().Print();
I read that interfaces do not have a constructors, which means it will not call super() of its super class. I also read that each and every class in Java is a subclass of Object
What about an interface, is it subclass of Object? Why?
No it's not. An interface cannot be instantiated to form an object, it is not a class.
An interface is a named collection of method definitions (without implementations). An interface can also include constant declarations.
Interface and class have some basic difference and one of them is do not have a constructors. Actually interface does not made for it and you cannot instantiate interface but there is way you can still instantiate interface.
interface Interface{
abstract String fun();
}
Interface interfc=new Interface() {
#Override
public String fun() {
return super.toString();
}
};
Type type=interfc.getClass();
Here interface has been instantiated as anonymous class.But still you cannot place constructor here according to java language specification. But still you can use super class Which will be immediately super class of this anonymous class.
An anonymous class cannot have an explicitly declared constructor.
And there is alternative solution of this that is using final variable in super class.
No interface is a subclass of Object class, since interface cannot extend a class whether implicit or explicit.
Reason for constructor is to create an instance, since interface cannot be instantiated as they don't provide any functionality they are just a contract only class can be instantiated hence they have constructor.
While some people suggest thinking of interfaces as "can-do" rather than "is-a" relationships, I think it's more helpful to think of them "is a __er" or "is a __able thing". To use a real-world analogy, a book (dead-tree edition), a bound paper magazine, a newspaper, a promotional advertising flyer, a sign, and a scrap of paper with some words written on it, are all "readable things". If someone were to show another person a book and ask "Is this a readable thing", the answer would be that it is. On the other hand, if someone were to show another person a book and ask "What is this?" the response would not be "A readable thing", but more likely "A book", or perhaps "A hardcover fifth-printing copy of the second U.S. edition of the novel 'Great Expectations' by Charles Dickens". Any type of "readable thing" has some identity beyond merely being a "readable thing".
Likewise with Java interfaces. An object may implement an arbitrary number of interfaces, but every object must have a type in addition to the set of interfaces it supports. Note that it is possible to define a method which will return a new object of unknown type that implements an interface; that would be equivalent to asking someone, "Please get me something to read" without specifying what type of object was desired. Such a method could select a type of object to return, and give the caller one which is "readable". Constructors, however, unlike general methods, require the caller to specify precisely what type of object is desired. Merely specifying that an object is "readable" would not be a sufficient specification.
No interface can not have constructor. Because interface support multiple inheritance. That means if a class inherit two interface then due to constructor chaining there will be ambiguity which constructor will be called from class constructor.