How to prohibit a subclass from having a method? - java

In my Java project, I have the method addType1AndType2() which has windows where you expand lists and select objects from the list. It was very complicated and time consuming to create, as things must be scrolled and xpaths keep changing. There are two lists in this which are actual names but, due to company proprietary info, I will just call them Tyep1 and Type2.
Now I have an UpdateType1 class which uses all the complicated methodology in the AddType1AndType2 but has nothing related to Type2 in it. I could copy the AddType1AndType2 and cut everything I do not need, but that would be replicating and changes would have to be duplicated in both classes. This defeats the purpose of inheritance and reusability.
I can make a class UpdateType1 extends AddType1AndType2{} which I have done. But there are still methods like selectType2Value() which are inherited but not possible in the subclass.
If I do an #Override and declare the class as private in the sub class, I get an error that I cannot reduce the visibility in a subclass.
Any idea what I can do? Right now I am just putting a throw new AssertError("Do not use") but that seems kind of lame. Is there a better thing to do that would even give a compile-time error rather than an assert at run time, or is this the best way?

The thing is: your model is wrong.
Inheritance is more than just putting "A extends B" in your source code. A extends B means: A "is a" B.
Whenever you use a B object, you should be able to put an A object instead (called Liskov substitution principle).
Long story short: if B has methods that A should not have ... then you should not have A extends B.
So the real answer is: you should step back and carefully decide which methods you really want to share. You put those on your base class. Anything else has to go. You might probably define additional interfaces, and more base classes, like
class EnhancedBase extends Base implements AdditionalStuff {
Edit: given your comment; the best way would be:
Create interfaces that denote the various groups of methods that should go together
Instead of extending that base class, use composition: create a new class A that uses some B object in order to implement one/more of those new interfaces.
And remember this as an good example why LSP really makes sense ;-)

Create the interfaces
public interface IAddType1 {... /* methods signtatures to add Type1 */}
public interface IAddType2 {... /* methods signtatures to add Type2 */}
public interface IUpdateType1 {... /* methods signtatures to update Type1 */}
then your current code at AddType1AndType2 will become just a base helper class:
public abstract class BaseOperationsType1AndType2{
//code originally at AddType1AndType2: methods that add Type1 and Type2
}
then your new AddType1AndType2 class will be:
public class AddType1AndType2
extends BaseOperationsType1AndType2,
implements IAddType1 , IAddType2 {
//nothing special.
}
and your new UpdateType1can be defined as
public class UpdateType1
extends BaseOperationsType1AndType2
implements IUpdateType1 {
//
}
Voila.

You can use 'final' keyword to prohibit extending a method in a subclass.
A method with a 'final' modifier cannot be overriden in a subclass.

Related

Why do we need abstract methods?

I have been studying abstract methods lately and I can't understand why do we need them?
I mean, after all, we are just overriding them. Do you know its just a declaration? Why do we need them?
Also, I tried understanding this from the internet and everywhere there's an explanation like imagine there's an abstract class human then there're its subclasses disabled and not disabled then the abstract function in human class walking() will contain different body or code. Now what I am saying is why don't we just create a function in the disabled and not disabled subclasses instead of overriding. Thus again back to the question in the first paragraph. Please explain it.
One of the most obvious uses of abstract methods is letting the abstract class call them from an implementation of other methods.
Here is an example:
class AbstractToy {
protected abstract String getName();
protected abstract String getSize();
public String getDescription() {
return "This is a really "+getSize()+" "+getName();
}
}
class ToyBear extends AbstractToy {
protected override String getName() { return "bear"; }
protected override String getSize() { return "big"; }
}
class ToyPenguin extends AbstractToy {
protected override String getName() { return "penguin"; }
protected override String getSize() { return "tiny"; }
}
Note how AbstractToy's implementation of getDescription is able to call getName and getSize, even though the definitions are in the subclasses. This is an instance of a well-known design pattern called Template Method.
The abstract method definition in a base type is a contract that guarantees that every concrete implementation of that type will have an implementation of that method.
Without it, the compiler wouldn't allow you to call that method on a reference of the base-type, because it couldn't guarantee that such a method will always be there.
So if you have
MyBaseClass x = getAnInstance();
x.doTheThing();
and MyBaseClass doesn't have a doTheThing method, then the compiler will tell you that it can't let you do that. By adding an abstract doTheThing method you guarantee that every concrete implementation that getAnInstance() can return has an implementation, which is good enough for the compiler, so it'll let you call that method.
Basically a more fundamental truth, that needs to be groked first is this:
You will have instances where the type of the variable is more general than the type of the value it holds. In simple cases you can just make the variable be the specific type:
MyDerivedClassA a = new MyDerivcedClassA();
In that case you could obviously call any method of MyDerivedClassA and wouldn't need any abstract methods in the base class.
But sometimes you want to do a thing with any MyBaseClass instance and you don't know what specific type it is:
public void doTheThingsForAll(Collection<? extends MyBaseClass> baseClassReferences) {
for (MyBaseClass myBaseReference : baseClassReferences) {
myBaseReference.doTheThing();
}
}
If your MyBaseClass didn't have the doTheThing abstract method, then the compiler wouldn't let you do that.
To continue with your example, at some point you might have a List of humans, and you don't really care whether they are disabled or not, all you care about is that you want to call the walking() method on them. In order to do that, the Human class needs to define a walking() method. However, you might not know how to implement that without knowing whether the human is or isn't disabled. So you leave the implementation to the inheriting classes.
There are some examples of how you'd use this in the other answers, so let me give some explanation of why you might do this.
First, one common rule of Object Oriented Design is that you should, in general, try to program to interfaces rather than specific implementations. This tends to improve the program's flexibility and maintainability if you need to change some behavior later. For example, in one program I wrote, we were writing data to CSV files. We later decided to switch to writing to Excel files instead. Programming to interfaces (rather than a specific implementation) made it a lot easier for us to make this change because we could just "drop in" a new class to write to Excel files in place of the class to write to CSV files.
You probably haven't studied this yet, but this is actually important for certain design patterns. A few notable examples of where this is potentially helpful are the Factory Pattern, the Strategy Pattern, and the State Pattern.
For context, a Design Pattern is a standard way of describing and documenting a solution to a known problem. If, for example, someone says "you should use the strategy pattern to solve this problem," this makes the general idea of how you should approach the problem clear.
Because sometimes we need a method that should behave differently in its instances.
For example, imagine a class Animal which contains a method Shout.
We are going to have different instances of this Animal class but we need to implement the method differently in some cases like below:
class Animal:
/**
different properties and methods
which are shared between all animals here
*/
...
method shout():
pass
class Dog extends Animal:
method shout():
makeDogVoice()
class Cat extends Animal:
method shout():
makeCatVoice()
dog = new Animal
cat = new Animal
dog.shout()
cat.shout()
So dog shouts like dogs, and cat shouts like cats! Without implementing the shared behaviors twice
There is a different behavior of shouting in these instances. So we need abstract classes.
Suppose you don't know about implementation and still want to declare a method then we can do that with the help of abstract modifier and making it an abstract method. For abstract method only declaration is available but not the implementation. Hence they should end with ;
Example:
public abstract void m1(); // this is correct
public abstract void m1(){ ... } // this is wrong
Advantage: By declaring abstract method in parent class we can provide guideline to child classes such that which methods are compulsory to implement.
Example:
abstract class Vehicle{
abstract int getNoOfWheels();
}
Class Bus extends Car{
public int getNoOfWheels(){
return 4;
}
}
If you want the short answer, think of this:
You have an abstract class Car.
You implement 2 classes that extend it, Ferrari and Mercedes.
Now:
What if you did one of the following, for the method drive(), common to all cars:
1) changed the visibility of the method,
2) changed the name of the method from driving to Driving,
3) changed the return type, from a boolean to an int
Think about it. It might not seem to make any difference right, because they are different implementations?
Wrong!
If I am iterating through an array of cars, I would have to call a different method for each type of car, thereby making this implementation of abstract useless.
Abstract classes are there to group classes with a common template, that share common properties. One way this helps would be the looping over the array:
Abstract methods ensure that all cars declare the same method,
and therefore, any object of a subclass of Car will have the method drive(), as defined in the abstract class, making the for loop mentioned easy to implement.
Hope this helps.

How can I restrict arguments of methods in abstract classes for subclasses that use them?

I've been trying to design a set of classes to model a classic RPG. I've found myself confused on how to solve this one issue, however: how do I force the use of character-type (e.g. Tank, Healer, DPS) specific spells/equipment, etc. in an abstract class. The example below better articulates what I mean.
I've got an abstract PlayableCharacter class which all character-types inherit from:
public abstract class PlayableCharacter {
private Set<Spell> mSpells;
...
public void addSpell(Spell spell) {
mSpells.add(spell);
}
}
For example:
public class Healer extends PlayableCharacter { ... }
public class Tank extends PlayableCharacter { ... }
Note the Set of Spell in the abstract class. I would like it if each subclass of PlayableCharacter could use its addSpell method but with the restriction that the type of Spell correspond to the PlayableCharacter subtype.
For example I have these Spell classes:
public abstract class Spell { ... }
public class HealerSpell extends Spell { ... }
public class TankSpell extends Spell { ... }
I only want Healers to use HealerSpells and Tanks to use TankSpells, etc. For example:
PlayableCharacter tank = new Tank();
tank.addSpell(new TankSpell()); // This is fine
tank.addSpell(new HealerSpell()); // I want to prevent this!
I thought of giving each subclass of PlayableCharacter it's own Set of subclass-specific Spells, but that creates a lot of code duplication.
I also tried making PlayableCharacter.addSpell marked as protected, then each subclass would have to implement an interface like this:
public interface Spellable<T extends Spell> { void addClassSpell(T spell); }
and each subclass that implements it would call super.addSpell(spell); but that lead to more code duplication and nothing was forcing those implementations to do the super call.
Is my strategy fundamentally flawed in some way? Any advice? I feel like this issue will keep getting worse as I add more character-type-specific equipment, traits, and so on.
I wouldn't do it that way (via type inheritance). It would be better to add characteristics to a Spell itself because it's a spell, which can be cast by a certain character only. Also, a specific spell can be cast to a certain character type only. These rules belong to a spell, not to a character.
Spell rules can be checked in a runtime by a separate class or by a Spell class itself inside a cast() method or another one.
so far what you have is good
the rest of the stuff, think more strategy pattern than super call
so abstract class can have algorithm that does step1, step2, step3 with possible parent implementation
child classes can override it, but only override parts that is different
when you call algorithm, it performs all steps
Steps themselves could be different class that has logic, if everything becomes too big
maybe have each subclass of playable character store the class (or classes) of subspells that are allowed. then do an if(spell instance of allowedSpell) ...

Can I have an empty Java class?

I'm creating a grid based game.
I need to implement a set of obstacles that take random positions within the grid.
I've created an abstract class ALifeForm, that holds the common methods for every item within the grid. Obviously, abstract classes can't be initialised, so I was going to create a new class AObstacle, which will extend ALifeForm.
Only issue is, my AObstacle class isn't specialised. All the methods it needs are within ALifeForm.
Can I have an empty class?
Is it bad programming practice? And if so, what can I implement instead?
Of course...
class AObstacle { }
(Plus whatever inheritance model you're using.) There's nothing stopping you from doing this.
Remember that a class isn't really a thing that you're defining. A type is. The class is just the language/syntax construct used to describe the type. If the type being described has no attributes or operations aside from the inheritance model, then there's nothing else to add to it.
Though you are adding one thing. You're giving it a name. It doesn't sound like much, but defining a semantic concept with a concrete name (particularly in a statically typed environment) is very important. Your type now has an identity apart from other types in the system. If things are added to it later, there's a place to add them without refactorings and breaking changes.
Well to do it you don't need to have an abstract class and a class that extends it, or an empty class(wich is possible too).
First way:
You just need to implement two classes: The class that contains the methods and the variables you need to use and the second calss that has an instance of your first class:
public class A{
public void firstMethod(){
//do your stuff here
}
....
}
public class B{
public static void main(String[] args) {
A a=new A(); //instantiate your class here
a.firstMethod();// then just use its methods
}
}
Because if you implement a class that extends an abstract class it should implement all its methods.
Second way:
Or if you want your second class to be specialized you could have :
your first class wich should not be abstract and the second one can extend it and use all its methods, and have its specific methods

2 Different java classes,exact same methods but one implements an interface

Suppose, there are two java classes.
BaseA
public class BaseA extends ModuleBase{
public void doSomething{
//does something
}
}
BaseB
public class BaseB extends ModuleBase implements
SomeInterface {
public void doSomething{
//does something
}
}
SomeInterface
public interface SomeInterface {
public void doSomething();
}
so as you can see the only difference between BaseA & BaseB is that BaseB implements an interface. As far my understanding an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. It cannot be instantiated.
Questions:
it seems BaseA & BaseA would be same as the methods & code in them is same. correct?
Interface seems like a contract that spells out how software APIs interact with each other & have no effect on class functions. only purpose of interface is to enforce that BaseB has mandatorily implement doSomething, where as with BaseA, its optional & won't generate compile errors. if not, then why?
What difference implementing an interface make? I know you have to implement all methods of that particular interface but if can also you do that without the keyword implements InterfaceName as seen in BaseB Vs BaseA where we implemented exact same doSomething(). what difference having the keyword implements InterfaceName in class declaration make?
No. Classes in Java are the same when they have the same fully qualified name and when they were loaded from the same classloader. Java makes no attempt to look into methods and it doesn't compare method signatures.
Or to put it differently: Java doesn't support duck typing.
Usually, interfaces are used to make a bunch of classes easily interchangeable. So you have something that needs a certain functionality. Instead of typing this to a single class, you can use an interface. People using that service can then feed it with different classes, according to their needs, making the service much more flexible (and somewhat harder to understand).
It means you can use BaseB in any place where InterfaceName is expected. That makes BaseB (and everything derived from it) much more useful/powerful.
Example:
If you want to check passwords, you can write a PasswordService class. But that means everyone has to use this class and live with the limitations.
If you offer a PasswordService interface, then users of your code can have different implementations: They can get passwords from a file, a database, LDAP, ... or for unit tests, they can write a service that says yes or no to every password.
what difference having the keyword implements InterfaceName in class declaration make?
You can then cast to that interface.
Java is not duck-typed.
Even if your class has a method void run() like a Runnable, you still won't be able to give it to places that want a Runnable without implementing the interface.
new Thread(instanceOfMyNotRunnableClass); // won't compile
Two classes are not same by their code. The code may be same but classes are still different. Two classes with same code may behave similar but will not be same.
To understand purpose of Interface, you should understand concepts of Abstraction and Encapsulation. Interface not only provides a contract, also provides an abstraction over underlying classes. You may write an API that takes object of type Interface without bothering about actual class implementing the Interface.
You can use BaseB in place where InterfaceName but you should not. This makes your code rigid for using only BaseB, whereas you may write an utility that takes any class that has implemented the interface.
Well, I assume that SomeInterface declares "doSomething", right?
If that's the case, the benefit for you is that you can treat BaseB as SomeInterface. Let's say you have another class BaseC, which also implements SomeInterface, then this code is valid:
SomeInterface inter = new BaseB();
inter = new BaseC();
while this is not valid:
SomeInterface interr = new BaseA();
Your advantage is, that you do not have to know, if inter is BaseB() or BaseC(), because you simple work on the interface declared methods, no matter how the implementation excatly looks like.
Interface is used to make skeleton of your API. Like java.util.ArrayList and java.util.LinkedList both are classes which implement interface java.util.List.
So if you have method like below
void doSomething(java.util.List list){
}
You can pass java.util.ArrayList or java.util.LinkedList as per your requirment with no harm.You don't have to create two diff. methods where one accept java.util.ArrayList and another accept java.util.LinkedList

How is abstract class different from concrete class?

I understand WHY we need Abstract Class in Java - to create sub-classes. But the same can be achieved by concrete class. e.g. Class Child extends Parent. Here Parent can very well be abstract & concrete. So why do we have ABSTRACT??
Abstract classes cannot be instantiated directly. Declaring a class as abstract means that you do not want it to be instantiated and that the class can only be inherited. You are imposing a rule in your code.
If you extend your Parent/Child relationship example further to include a Person class then it would make good sense for Person to be abstract. Parent is a concrete idea and so is child. Person is an abstract concept in reality as well as in code.
One benefit is that you explicitly define and protect the idea of the abstract class. When you declare a class as an abstract there's no way that you or anyone else using your code uses it incorrectly by instantiating it. This reasoning is similar to why we specify functions and fields as public, private or protected. If you declare a function or member as private you are in effect protecting it from improper access from client code. Privates are meant to be used within the class and that's it. Abstract classes are meant to be inherited and that's that.
Now, do you have to use abstract classes and define functions and fields as private instead of public? No, you don't. But these concepts are provided to help keep code clean and well-organized. The abstract class is implemented in all object-oriented languages to my knowledge. If you look around you will see that C++, C#, VB.NET etc. all use this concept.
A better, specific example:
In the example above the Shape class should be abstract because it is not useful on its own.
Abstract class means it is abstract not complete. It needs another class to complete it and/or its functionalities. You need to extend the abstract class. It will be useful with Certain class eg. Fruit all fruits have the same property like color. But you can have different properties for different fruits like is it pulpy such as orange or not eg Banana etc.
I know this is an old question but it looks like the poster still had some questions about the benefit of using an abstract class.
If you're the only one who will ever use your code then there really is no benefit. However, if you're writing code for others to use there is a benefit. Let's say for example you've written a caching framework but want to allow clients to create their own caching implementation classes. You also want to keep track of some metrics, like how many caches are open, hypothetically. Your abstract class might look something like this:
public abstract class AbstractCache {
public final void open() {
... // Do something here to log your metrics
openImpl();
}
protected abstract void openImpl() { }
}
On its own the AbstractCache class is useless and you don't want clients to try to instantiate one and use it as a cache, which they would be able to do if the class was concrete. You also want to make sure they can't bypass your metric logging, which they would be able to do if you just provided them a Cache interface.
The point of abstraction is not to create sub-classes. It's more about creating Seams in your code. You want code to be test-able and decoupled which lead to the ultimate goal of maintainability. For similar reasons, abstraction also buys us the ability to replace a bit of code without rippling side effects.
An abstract class is meant to be used as the base class from which other classes are derived. The derived class is expected to provide implementations for the methods that are not implemented in the base class. A derived class that implements all the missing functionality is called a concrete class
According to my understanding
Abstract Class is a class which just describes the behavior but doesn’t implement it.
Consider this Java example for Abstract Class:
public interface DoSomething(){
public void turnOnTheLight();
}
Concrete Classes are those, which are to be implemented.
For Example:
public abstract class A(){
public void doIt();
}
public class B extends A(){
public void doIt(){
//concrete method
System.out.println(“I am a Concrete Class Test”);
}
}
In other words, A concrete class in java is any such class which has implementation of all of its inherited members either from interface or abstract class.
For those who seek only differences in pure technical approach, the clearest difference between concrete parent classes and abstract parent classes is the obligation for children to include/implement specific methods.
A concrete parent class cannot force/oblige its children to include/implement a method. An abstract parent class oblige its children to do that by declaring abstract methods.
Apart from the above, it comes to design and functional requirements to dictate the use of abstract class. Such examples can be found on javax.servlet.http.HttpServlet class

Categories

Resources