Using java abstract class - java

In my UI project, I have few screens that share the same header style only the text is specific to the screens. What will be a good way to implement this?
Have the super class create all the header component and open the components to the sub class, the sub class will access to component's setText method to update the text?
or
Have abstract method in super class to create the components, sub class will implement these methods to create the component.
Hope it make sense..

Do you really need an abstract class?
public class UIScreen {
public UIScreen(String headerText) {
//set everything up here w/ the right text
}
}
// elsewhere ....
UIScreen mainScreen = new UIScreen("Main Screen");

Create the abstract class with the generic header method, and define one method for all the subclasses to implement would be best.

Depends on whether you want the super class able to be instantiated or not. It's like having an Animal super class and Dog and Cat subclasses. Do you want people to be able to create a generic Animal?
If so, it should be a normal class. If not, it should be declared abstract.
So ultimately the question is: Is there a default behavior? If not, then make it abstract.

The second option is more viable.
Remember: Single Responsibility Principle
Both options work but the second one will go a longer way to reduce coupling in your code.

When the behaviour Keeps changing...encapsulate it in either abstact class or interface.
Its better to have an
Abstract class, with the non-abstract method to create the Header,
and an Abstract method to create the text
..In the sub class u can create the text of your choice by implementing the abstract method.

"Have abstract method in super class to create the components, sub class will implement these methods to create the component."
In my opinion this solution is easier to maintain.

You can change your option 1 slightly
public abstract class SuperUI {
private HeaderComponenet headerComponent;//have getter setter
}
public class BaseUI extends SuperUI{
private void changeHeaderComponent(){
headerComponent.setText("Changed");
}
}
public class HeaderComponent extends JComponent{
public HeaderComponent(){
//create the default header here
}
}
In this case if the default header component has to be changed you don't have to change your SuperUI, as you have separated the header from SuperUI, you can do the same for footer component if need be.

My question is does the subclasses have any useful functionality? If not, why wouldn't you just have the one concrete class and pass it some sort of data container to populate the fields?
If there's no behavioral differences, you'd be much better served just passing data and/or collaborators into either the constructor, or via property setters.

Related

Abstract class with little used abstract method - should I make concrete?

Let's say I have a class called GUIElement described by this code:
public abstract class GUIElement {
public abstract void onScroll();
//Other methods such as getX(), getY(), onClick() etc.
}
All GUI elements that extend this are obviously forced to write concrete code for onScroll provided they are a concrete class, but very few actually use this onScroll method as it is only handy in something like a long GUIText block.
My question is then, what is the best practice in this situation? Continue to force all child classes to write code even when mostly it will be empty, or make it concrete like so:
public abstract class GUIElement {
public void onScroll() {}
//Other methods such as getX(), getY(), onClick() etc.
}
and have the few classes that use it just override it.
Or maybe there are other, better alternatives?
If only a few classes need to implement the method, then the Adapter Pattern is a good choice. Which is, what your second approach basically is. Have an empty implementation in the parent class and only those child classes that need this functionality can override it, but they're not forced to do so.
Take a look at the MouseAdapter in the AWT package for instance. It implements the MouseListener interface, but leaves all methods empty. Child classes then can choose whether to override those methods or not.
Let's say I have a class called GUIElement described by this code:
public abstract class GUIElement {
public abstract void onScroll();
//Other methods such as getX(), getY(), onClick() etc.
}
All GUI elements that extend this are obviously forced to write concrete code for onScroll provided they are a concrete class, but very few actually use this onScroll method as it is only handy in something like a long GUIText block.
In an abstract class methods should be abstract because concrete methods in this abstract class use them, e.g.:
public abstract class GUIElement {
public void onScroll(){
// do stuff
SomeObject retunValue = calculateInSomeChiledClass();
// do other stuff
}
potected abstract SomeObject calculateInSomeChiledClass();
}
An abstract class should not have abstract methods for any other reason.
Make an empty concrete method is a way but it has a consequence as it doesn't force new declared class to override it.
If this consequence is not a drawback for you, using this way is fine.
Otherwise, if you want to be sure that subclasses specify explicitly how to implement the operation, you should keep the method as abstract and implement them when it is required and throwing UnsupportedOperationException or an empty implementation in the subclasses where the operation is not supported.
Both solutions are acceptable.
Follow the one or the second depends on the point that you want to stress on for your subclasses : simple API or explicit behavior to define.

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) ...

How to prohibit a subclass from having a method?

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.

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

Extend a returned Instance

I'm a Java newbie and ran into a bit of a problem. I want a class to become another class. It's hard to explain it the abstract way, so I'll give you an example.
public class WorldGuard extends WorldGuardPlugin {
public WorldGuard(Plugin parent) {
WorldGuardPlugin plugin = parent.getServer().getPluginManager().getPlugin("WorldGuard")
// make plugin the actual class
}
}
WorldGuard should act like some kind of a wrapper here. When constructed it gets one parameter parent on which base it finds an instance of WorldGuardPlugin. The class should now become that instance.
It's simple in JavaScript, I just return the instance, but I can't do this in Java.
I'm not quite sure what you're trying to do. A class cannot "become another class". But perhaps your problem is just that you're trying to use a constructor when you should be using a plain function. Maybe what you want to do is this:
public class WorldGuard extends WorldGuardPlugin
{
public static WorldGuard getFromPlugin(Plugin parent)
{
return (WorldGuard) parent.getServer().getPluginManager().getPlugin("WorldGuard");
}
}
That would get the object via parent and return it as a WorldGuard object.
Class cannot become other class.
I think you can choose among the following possibilities.
User Factory that creates instance of your classes. The factory will choose concrete class according to any logic you want and create instance of "right" class. If you want all classes the factory operates with can implement specific interface, so caller will not even know instance of which class is created.
Use wrapper pattern. In this case your actual WordGuard class will wrap actual instance of other class and delegate all calls there.
Use dynamic proxy or byte code engineering solution. But it is much more complicated and is not the best solution in most cases.
You should call the copy constructor of WorldGuardPlugin. What I mean is that WorldGuardPlugin should have a constructor that can create a copy of a given instance of the class like:
WorldGuardPlugin pg = new WorldGuardPlugin(anInstance);
If this is the case then you are in luck. You can simply do:
public class WorldGuard extends WorldGuardPlugin {
public WorldGuard(Plugin parent) {
super( parent.getServer().getPluginManager().getPlugin("WorldGuard"));
}
}
This will make "WorldGuard act like some kind of a wrapper here". You can still call the methods defined in WorldGuardPlugin on an instance of WorldGuard while being able to add methods to WorldGuard itself.
You can't change the type of object being constructed in a constructor. A constructor, by definition, constructs that class (e.g. A's constructor creates a type A).
In your example, WorldGuard extends WorldGuardPlugin, which means that WorldGuard is a type of WorldGuardPlugin. Maybe there is a way to initialize the WorldGuardPluin class (using a call to super in the constructor) with the properties that you want.

Categories

Resources