Java - Abstract class into normal class - java

public abstract class Figure
{
private int offset;
public Figure()
{
offset = 0;
}
public Figure(int theOffset)
{
offset = theOffset;
}
public void setOffset(int newOffset)
{
offset = newOffset;
}
public int getOffset()
{
return offset;
}
public abstract void drawHere();
/**
* Draws the figure at lineNumber lines down from the
* current line.
*/
public void drawAt(int lineNumber)
{
int count;
for(count = 0; count < lineNumber; count++)
System.out.println();
drawHere();
}
}
In this class, it handles the figure for creating a tree. I am trying to turn it into a normal class by simply giving a body to the abstract method. I noticed that when I remove the abstract tags, it still works perfectly normal. But my question is, if I want to make the class non-abstract, through what means would I go through to do this?
This class is extended upon by 2 other classes and then it has the main class. Do I have to go through and modify those too?

You shouldn't be altering Figure; you should be extending it.
This class is extended upon by 2 other
classes and then it has the main
class. Do I have to go through and
modify those too?
All the more reason to not alter Figure: you'll break the rest of the code.
You should not be modifying anything. Create a new class that extends Figure and override the abstract drawHere() method with the behavior you want.

When you have an abstract class,
abstract class AbstractCar {
float maxSpeed;
Driver whoIsDriving;
AbstractCar(float ms, Driver d) {
maxSpeed = ms;
if(!validateDriver(d)) throw new InvalidDriverException();
whoIsDriving = d;
}
abstract boolean validateDriver(Driver d);
}
You can define the behavior separately for various conditions by extending and defining the abstract methods in question.
class CrappyCar extends AbstractCar {
boolean validateDriver(Driver d) {
return d.hasLicense() && d.hasInsurance();
}
}
class ExpensiveCar extends AbstractCar {
boolean validateDriver(Driver d) {
return d.hasLicense() && d.hasInsurance() && d.hasGoodJobInCaseHeMessesUpMyCar();
}
}

If you want a non-abstract class, then you must not declare it with the abstract modifier (i.e. just public class Figure). There shouldn't be any need to modify any derived classes (so long as they themselves are not abstract).

Technically speaking, in order to make an abstract class non-abstract you have to:
Provide implementation for all abstract methods
Since you now have a valid implementation of everything define, remove all abstract tags
There is no need to modify anything in inheriting classes (assuming they are non-abstract theirselves) because they already provide an implementation of all the abstract methods of their parent & are free to override any method they wish.
Whether or not you should make your class non-abstract is another point of discussion.

You are correct that removing the abstract keywords and implementing the abstract methods makes the class non-abstract.
However, you normally do not want to turn the class itself from abstract to non-abstract. A class is not abstract until you add this keyword, so you (or someone else) apparently had a reason to make sure it's not a normal class, but an abstract one.
If you think about it at a very high level (far from Java), then a "Tree" is something you know how to draw. Similarly, you could imagine a subclass "Circle" for which you know what a drawing shoud look like. For the very generic "Figure", however, you have no idea what it means to draw it.
This is the idea of why the actual drawing is left abstract in your Figure class. Hence, you should not make Figure non-abstract, but instead focus on the classes that extend from it and make those non-abstract, by implementing all abstract methods from Figure. In your Tree class, you know what drawHere should do, so implement it there to print a tree. In another class, like Circle you implement it differently, but it never really makes sense to implement it in Figure, where you have no idea what to draw.

You can declare a method body for drawHere() (presumably empty, since, as #Frank pointed out, you can't really have any idea about how to draw a Figure) and remove the abstract modifiers. Then you will have a concrete class. That means someone could create a new Figure(). This won't be either of the two subclasses you now have, just a Figure.
If such an object (that does nothing when it is called upon to drawHere()) would not be useful (and, in particular, if you would consider it an error to have such an object), then you should keep the class abstract. This reasoning applies even when you can define an implementation for every method.

If a class is made abstract you can give body to all the methodes or none of these but if any class is extending abstract class it must implement all the methode which is only being declared.

Related

Referencing instance variables from within abstract class

I have an abstract class which lays out what each of its subclasses should implement. Most methods will have different implementations for each subclass, but some will be the same for all. I want the methods that will be the same to be to be defined in the abstract class, so that I'm not pasting the same method into several different classes. However, when I call that method on an instance of the abstract's subclass, I receive a nullpointer because, I imagine, the method implemented in the abstract class is referencing the abstract's field, not the instance's field.
Can someone point out where the flaw is?
For example:
abstract class ControlView {
String[] controls;
abstract void render();
void release() {
for (int i = 0; i <= controls.length; i++) {
//Release the controls
}
}
}
class StartingControls extends ControlView{
String[] controls;
Button uiDrawButton;
Button uiLoadButton;
StartingControls() {
this.controls = new String[2];
uiDrawButton = new Button();
this.controls[0] = uiDrawButton;
uiLoadButton = new Button();
this.controls[1] = uiLoadButton;
}
public void render() {
//Unique Render implementation
}
}
When I call
instanceOfStartingControls.release();
I obviously want to iterate over the two strings that I put into instanceOfStartingControls' controls field when it was constructed. I do not want to iterate over the non-initialized array that is apparently living in the abstract.
Is it some combination of access modifiers or static methods that is keeping this from working as it seems it should, or am I missing some crucial bit of knowledge on abstract classes? This feels like a basic question, but I'm having a hard time putting it to words, so I've not been satisfied with any results from my searches.
There are two arrays called controls. The one in the derived class is obscuring the one in the base class, thus the base instance never gets set non-null.
Delete the declaration from the derived class.
This issue is not related to the base being abstract. If you use the same field name in a derived class as is used in a base class, the base instance will be obscured.

Cannot pass super keyword as an argument to method in java

Why below program does not work fine?
instead of super in below code if we give this keyword as an argument it will work fine, what is the difference between two codes.
Thanks in advance
class Vehicle
{
int maxSpeed = 120;
}
/* subclass Car extending vehicle */
class Car extends Vehicle
{
int maxSpeed = 180;
void display()
{
test(super);
/* print maxSpeed of base class (vehicle) */
// System.out.println("Maximum Speed: " + super.maxSpeed);
}
public void test(Vehicle obj)
{
System.out.println("Maximum Speed: " + obj.maxSpeed);
}
}
/* Driver program to test */
class Test
{
public static void main(String[] args)
{
Car small = new Car();
small.display();
}
}
There is a misconception on your end. this refences to a real object, therefore you can pass it to any method that allows for an instance of the corresponding class.
But there is no separate super object! super is nothing but a helper mechanism that allows you to access methods or fields of the super class (and it only works within a derived class). It is not intended to deliver a real object refence!
And note: that also doesn't make sense conceptually. You can't really separate the super class properties when looking at a child class due to polymorphism.
It is really simple: you pass this, nothing else. If your code doesn't work then, then that would be a symptom of a bug in your design!
Welcome to StackOverflow.
Your method test receives a instance of a Car, and keyword super it's used to call parent methods, through child class. this keyword returns the instance of the class.
What you're trying to achieve is call super() constructor to pass a instance of a Car to the method, but java states that the the super() call can be used only once in the constructor class as the first statement, to ensure that class will inherit from it's parent, or Object class directly. If you not states it, Java implicitly does it for you.

Confusion about extended classes in Java

I am having some confusion about extended classes. I think the best way to explain what I want to do is with some skeleton code:
abstract class Player
{
public int solve()
{ // One method of solving problem
}
}
class otherPlayer extends Player
{
public char solve(int num)
{ //Different method of solving same problem
}
}
// I suspect this is a wrong way to create Player
Player first = new otherPlayer;
// Because this gives me an error...
first.solve(5)'
// And this uses the super class's method of solving problem
first.solve();
// I don't want to do this though...
otherPlayer first = new otherPlayer;
// Because I actually define the Players in a method
// that returns a type Player():
private Player genPlayer()
{ // Take input from keyboard
Player newPlayer;
if (specific set of answers)
newPlayer = new otherPlayer();
else newPlayer = new Player();
return newPlayer;
}
My understanding of extended classes is limited. If I say "TypeA var = new TypeB", and TypeB extends TypeA, it seems that var only has access to methods in the TypeA class. What does it do, then to say it is a new TypeB? Why is that even a legal way to instantiate a variable? And how would you recommend I restructure this program so I can make it work (I'd prefer to keep the method, so I don't have to make a mess every time I create a Player)?
I really just want to know how to create an extended class as if I were a person who knew what he was doing.
You need to do something like:
abstract class Player {
abstract void solve(int num);
}
class OtherPlayer extends Player {
void solve(int num) {
//...
}
}
That is, to call a method through variables of type Player, at least its signature must be declared on that class - and must be implemented in all subclasses. There is no way to call a method that may or may not exist in a subclass using a variable of the superclass type.
Imagine you could do this:
class Player {
// ...
}
class FooPlayer extends Player {
void solveInt(int num) {
// ...
}
}
class BarPlayer extend Player {
void solveString(String s) {
// ...
}
}
Player[] players = new[] {new FooPlayer(), new BarPlayer()};
// this is the sort of code you want to work
for (Player p : players) {
p.solveInt(123);
}
what's supposed to happen when the method is called on BarPlayer? As you can see, it doesn't make much sense to allow this.
While it's not very useful to do Player player = new FooPlayer() explicitly, it does let you not have to know which exact subtype of Player the value is. It's missing the point to look at the methods that are different between the subtypes - the point of polymorphism is that the same method (i.e. with the same signature) is implemented in a different way between the subclasses:
class Player {
abstract String greet();
}
class EnglishPlayer extends Player {
String greet() {
return "Hello";
}
}
class JapanesePlayer extends Player {
String greet() {
return "Konnichi wa";
}
}
The point of TypeA a = new TypeB() is programming to contract. It means you can change TypeB into any other type that extends TypeA and be guaranteed not to have to change any other line of your code.
first, you are getting an error in the instantiation syntax. It should be new otherPlayer(). Also classes should be capitalized in java.
I assume the code is within a method, otherwise it will not compile.
Finally, to answer your question why you extend a class, if otherPlayer had its own implementation solve() (no arguments) then which method would be called would depend on the instantiation you used, not on the variable type. In other words, first.solve() would call the method in otherPlayer, not in player.
extension is about superclasses and subclasses.
if typeA is a subclass of typeB, then you could say
typeA extends typeB, and typeA would inherit all of the methods of typeB
it only works one way, kind of like a child can inherit traits from their parents, but the parents don't inherit anything from the child
if you want a method in the subclass to behave differently than in the parent class, simply write a new method with the same name/parameters. subclass methods automatically override superclass methods. then, if you want to use the superclass version of a method, you can use the super keyword
Inheritance is something that happens when you extend a class, you need to figure out the common methods you want in your class and subclass and define any alternates in your subclass.
Check this out for more info: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
you declared 'first' as a Player reference that is referencing an otherPlayer object. This is legal, but if you want otherPlayer behavior, you will have to typecat 'first':
((otherPlayer)first).solve(5)
First of all, you can't instantiate abstract classes, so you can't code newPlayer = new Player();.
Then, it's perfectly legal to write something like ClassA a = new ClassB(); as long as ClassB is a subclass of ClassA and ClassB is not an abstract class.
In the case you have a method in ClassB that overrides a method of ClassA, which one is called depends on the dynamic type of the object that is actually the type you used for instantiate that object, this is called Polymorphism. There is lot of material about this (Object Oriented Programming and Java) on the web, but I think a great place to start at, is the book Thinking in Java by Bruce Eckel, he offers the third edition for free at his site (http://www.mindview.net/Books/TIJ/).

setting superclass fields in subclass

I have an abstract Java class that has a hashcode field that should be initialized by the concrete subclasses. I was thinking of making the initialization method abstract, i.e.,
abstract class A {
protected int hashcode;
// hashcode should be initialized in constructor
protected A () { hashcode = setHashcode(); }
abstract int setHashcode() {} // implemented by subclasses
}
But unfortunately different subclasses need to take in different number of arguments for setHashcode, e.g., class B might compute hashcode using two of its fields and class C might need three, but since the call to super has to be the first line in B's constructor this scheme won't work. So I am wondering if there is a different way / design pattern to solve this problem?
but since the call to super has to be the first line in B's constructor this scheme won't work
Why wouldn't it work? If you put calculations of the hash code in a static function of a subclass, you would be able to pass pre-made hash code to the constructor of your superclass.
class BaseClass {
private int hashCode;
protected BaseClass(int hashCode) {this.hashCode = hashCode;}
}
class DerivedClass : BaseClass {
private static int calcHash(String str) {
return str.hashCode();
}
public DerivedClass(String s) {
super(calcHash(str));
}
}
You don't really need to store the value in the superclass, just declare an abstract getHashCode that subclasses will override.
public abstract class Base {
protected abstract int getHashCode();
}
This is better because the "intent" of the method is preserved, regardless of its storage requirements.
Incidentally, hashCode is already defined in Object, and can be overridden by subclasses. If your concept of hash code is different than what Object provides, maybe you should rename it.
It sounds like an interface might be appropriate for the initialization so any subclasses you create can just overload the interface implementation.
Change:
abstract int setHashcode();
To:
abstract int getHashcode(Object...objects);
And the subclass needs to inspect the count and type of objects passed.
Then you make calls like:
hashcode = getHashcode();
hashcode = getHashcode(o1);
hashcode = getHashcode(o1,o2);

How to by-pass inheritance in java when invoking a method

class Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Super " + s;
}
}
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
if suppose in main,
Super s = new Sub();
s.anotherMethod("Test");
Output will be, Sub Test
Can you anyone help me in telling how to get output Super Test with the given sequences in main.
And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.
Why would you ever want to do that ??
The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...
Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.
And let me explain why I want this,
say I have a class which has method
test() and it's can be overriden by
sub classes, some cases I want the
overriden test() and in some cases
test() of super class itself, there
are many ways to do this, it will be
helpful if anyone can be best
solution.
If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.
If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.
Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.
Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.
But in no case can you override a method and expect it to magically sometimes not be overridden.
You would have to go the route of:
Super s = new Super();
s.anotherMethod("Test");
...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.
class Sub extends Super {
public String anotherMethod( String s, boolean bSuper ) {
if( bSuper )
return super.retValue(s);
else
return retValue(s);
}
public String retValue(String s) {
return "Sub " + s;
}
}
From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.
The runtime type of s is Sub, so you're only ever calling methods on that class.
Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.
If your child class was defined as:
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public void yetAnotherMethodString s) {
super.retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
and then call this new method in your main you would be able to print out "Super Test".
Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!
I'm hesistant to post this as an answer, since the question is quite horrible - but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.
So modifying the original example:
class Super {
public static void staticMethod(String s) {
System.out.println("Super " + s);
}
}
class Sub extends Super {
public static void staticMethod(String s) {
System.out.println("Sub " + s);
}
}
public static void main(String[] args) {
Super s = new Sub();
s.staticMethod("Test");
}
then main() will print out "Super test".
But still don't do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn't call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.
You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:
Super sub = new Sub() {
#Override
public String retValue() {
// re-implement Super.retValue()
}
};
otherObject.use(sub);
Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.
Can you anyone help me in telling how
to get output "Super Test" with the
given sequences in main.
Don't overwrite anotherMethod() and retValue() in Sub in the first place.
In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).

Categories

Resources