Two Laptop Bag*
The moose likes Beginning Java and the fly likes about abstract class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "about abstract class" Watch "about abstract class" New topic
Author

about abstract class

Harshada Deshmukh
Greenhorn

Joined: Mar 25, 2007
Posts: 12
Suppose I am writing abstract class which doesn't contain atleast one abstract method.Then also my code compiles.Then what is the use of declaring that class as abstract.
Example

public abstract class Abstractdemo
{
void display()
{
System.out.println("Hi");
}
}
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39884
    
  28
The point of having an abstract class is to force users to extend it. That may be appropriate, if that is how you have designed your application.
Harshada Deshmukh
Greenhorn

Joined: Mar 25, 2007
Posts: 12
Thanks I got it
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
There is no good reason to write an abstract class. The typical reason is code reuse, but there are better ways of achieving that. In the case presented, I'd make Abstractdemo be called FinalDemo, and be final, not abstract. Or, even better, make the method static, as it doesn't rely on anything from any instance.
pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
Originally posted by Ricky Clarkson:
There is no good reason to write an abstract class.

Let me place my tongue firmly in my cheek and state: "all generalizations are bad."

Surely there are places where an abstract class would be useful and even preferred?
[ March 28, 2007: Message edited by: pete stein ]
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
No, there are none. Post one and I'll show you better (or at least different) ways.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
By the way, all generalisations are great, because they express the writer's opinion very well. If I make a generalisation, you may find an exception, after consideration of which I may cease to use that generalisation.

Otherwise we're left with "in my opinion, most of the time, if you don't mind me saying so, gotos possibly aren't the best thing to use when you want to conditionally branch" instead of "gotos suck".
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Originally posted by Ricky Clarkson:
There is no good reason to write an abstract class. The typical reason is code reuse

I disagree. As you mention, there are lots of ways to reuse code, but that's not the best reason or even the "typical reason" to write an abstract class.

Abstract classes make it clear that the class is intended only for extension, and must never be instantiated. The reason to write an abstract class is to provide default behavior to all subclasses which they can either use or override as needed.

Yes, I know all about the argument that interfaces are better than superclasses, but an interface can't provide default behavior. For a simple class that needs one or two methods to do a job, an interface is fine. However, for a complicated scenario where many methods are required to do the job, it's very helpful to have default behavior to fall back on and only have to extend what is necessary and appropriate for a given scenario.


Merrill
Consultant, Sima Solutions
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
I prefer a builder approach for the case where you want default behaviour.

E.g.,

Person person=new Person().whenYouHitHim(Reactions.HITS_BACK).whenHeGetsHungry(Actions.EAT_KEBAB);

You could replace new Person() with PersonBuilder there, I'm not too fussy.

HITS_BACK could be an int, a dumb (as in without-functionality) enum constant, or a callback (such as a Runnable).

This isn't my argument against abstract classes, by the way, so don't treat this as a strawman to knock over.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
So, what's your point? How exactly is a builder approach better than using an abstract class? You've shown me a different way, but you haven't shown me that it's better.

If this isn't your argument against abstract classes, what is your argument?
[ March 28, 2007: Message edited by: Merrill Higginson ]
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18909
    
    8

I don't accept the argument that says "You can always do B instead of A, therefore there is no reason to do A".
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
A builder approach is better than an abstract class approach because it is simpler. You can look at each unit and see what it does. It's clear when you see a call to x() that it calls the implementation of x() that you can see, not that of some subclass.

Also, you can easily write a second builder implementation with different defaults, without having to change or duplicate the existing code. That helps in migration; you can keep one lot of defaults active, test the new implementation then swap it in. You can't do that with the subclassing approach - you'd have to make the superclass temporarily more complex, by, say, passing in a flag at construction that decides which defaults to use.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
I've made the above more concrete with actual code, here: http://docs.google.com/Doc?id=dx5mfkq_783qtg7n

You'll note that I still haven't made my case for abstract classes being useless. I'm not playing games, I just haven't got it in good enough words. If I say it badly it'll get shot down. I'll let the code speak.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Wow, thanks, Ricky! You've put a lot of effort into this explanation, and I for one have a much better understanding of the builder pattern and ways to use it. I will definitely be using it more now that I understand it better.

I will grant you that a builder pattern is the tool of choice where it is highly important to be able to swap out logic at run-time. The cost, however, is in complexity.

You say that a builder is simpler, but even your simple builder example was considerably more complex to write than the abstract example. In your example, the signatures were simple with few parameters and no return types, but in the real world they may be more complex. In this situation instead of just writing a method with whatever signature in an abstract class, I now have to create interfaces with method signatures for each process I plan on having the builder inject, and carefully handle the generics so that they are flexible enough, but not too flexible.

In a case where it is not anticipated that behavior will have to be changed at run-time, an abstract class is a simpler, and therefore better solution. I'm not convinced that the abstract class is a tool that I should throw out of my toolbox.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
The cost, however, is in complexity.


To my eyes, the builder way is actually less complex. I see a class whose instances have two public mutable fields, each of which represents a procedure. I don't see how it can get any simpler than that. What metric are you using for complexity? If it's keypresses/characters on screen, let's resume the discussion in 2009 when Java has closures. Or meanwhile, imagine my example scaled up to more complicated requirements.

In your example, the signatures were simple with few parameters and no return types, but in the real world they may be more complex.


You can write a single interface that represents any method with one input and one output, using generics. I call that Function.

Technically, though I'd say it's inadvisable, given a Pair class, you could implement a two-input method as a Function<Pair<Whatever,Whatever2>,Output>.

You could implement a three argument method by nesting Pairs. Ugly.

The usual solution is to write a Function2 interface that has two inputs and one output.

I'd really rather that generics supported a varargs syntax, so that this wasn't necessary, but I've not quite got my words together on that one either to be able to propose it to anyone.

Either way, it certainly works, in current Java, and it doesn't involve trillions of interfaces.

You don't have to 'carefully handle the generics', just use generics as you would normally. There's nothing harder in this than there is in general generics use.

In a case where it is not anticipated that behavior will have to be changed at run-time, an abstract class is a simpler, and therefore better solution.


That's not what I'm saying. You might want to swap out some defaults for some other defaults, when creating a new object. An abstract class applies its own defaults, and it's hard to make an abstract class apply different defaults to each object. Not that hard on a small scale, mind. It's also hard to make sure that if you don't want the defaults that an abstract class provides, that you've replaced them all. With an interface, it's easy to provide an alternative implementation, and it's easy to ensure that you haven't accidentally inherited any of your implementation from anywhere but java.lang.Object.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Again, thanks for your insights. I'm excited about trying out some of the methods for writing more flexible code that you've demonstrated. Generics have opened up a lot of avenues for writing this type of code that weren't available before.

I certainly don't see myself as the "defender of the faith" in defending the use of abstract classes, but I don't think you're justified in saying that using an abstract class is a bad coding practice, or saying that it should never be used.

Regardless of your protests, your example is clearly more complex than a simple abstract class. If you will look at your own code, you will see that it took over three times as many lines of code (38 compared to 11 not counting white space) in your builder example to accomplish the same thing the abstract example accomplished and it required the use of other artifacts that had to be built separately. Not to mention that it requires the use of more complex constructs such as anonymous inner classes. Granted, it's way more flexible, and sometimes is a better choice. There are times, though, when one simply doesn't need that kind of flexibility. I believe in the extreme programming principle of "build only what you need, and not what you think you might someday need".
With an interface, it's easy to provide an alternative implementation, and it's easy to ensure that you haven't accidentally inherited any of your implementation from anywhere but java.lang.Object.

That's not always a good thing! If I'm dealing with a complex process, and I'm writing a new extension to that process, I don't want to have to think about how every detail works, and have to rebuild it all. If I have a superclass I know works, and I know generally handles things the way I want to handle them, it's a good thing that I'm "accidentally inheriting" behavior, because I don't want to be in a situation where I have to remember and deal with every detail of the process. I just want to make one or two changes and trust that "accidental inheritance" will take care of the rest.

We could go back and forth on this forever, but I guess what I'm saying is that when you say "all Abstract classes are bad", you're taking on a tremendous burden of proof. You're basically calling anyone who has ever included abstract classes in their architecture an idiot, and saying that in all the myriads of cases, there's not a single case in which the use of an abstract class would be justified. I just don't buy that.

You have definitely changed my opinion, though. I'm now going to look harder at other options before opting for an abstract class.
[ March 30, 2007: Message edited by: Merrill Higginson ]
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
OO Programming style says that we should always visualise a problem/issue as a object model.

There is a very good example mentioned in HF book.
Like we make a inheritence tree with animal class as root and then derive many other classes like carnivorous , omnivorous and then we may extend the tree.Like tiger under carnivorous etc.This fits the OO view.But animal as such doesn't give us much idea about the type of animal and what its eating habits are.So it would be wise to make this Animal class as abstract.


Rahul Bhattacharjee
LinkedIn - Blog
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
If you will look at your own code, you will see that it took over three times as many lines of code (38 compared to 11 not counting white space) in your builder example to accomplish the same thing the abstract example accomplished and it required the use of other artifacts that had to be built separately.


You didn't scroll down far enough. Take a look at the last code sample. 14 lines of code, and less if you reformatted it to the usual Java style (braces on the ends of lines).

As it happens, I already have the other artifacts ready in a library called functionalpeas.

If we had BGGA closures, the final code would have looked like this:


That is, it is conceptually small and simple. If the syntax of a language makes that hard to implement, that's a fault of the language, not of the concept.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
OO Programming style says that we should always visualise a problem/issue as a object model.


Really? You can write procedural code and comply with that, if you say that every procedure is an instance of a class.

The example of carnivorous and omnivorous animals is actually a very good one for demonstrating OO gone wrong.

Human is a subclass of Omnivore, possibly indirectly via Mammal, etc. However, my ex-girlfriend, Jenny, is an instance of a subclass of Human (no offence meant to her), but is not an Omnivore. She is a Vegetarian.

The idea of a hierarchy instead of attributes automatically leads to monolithic, inflexible models. What would you do with Jenny there? Pretend she's an Omnivore? You're losing information, or your hierarchy will explode in size.

If you simply had an Animal class, with one attribute, stuffItWillEat, that would represent everything in this very limited case.

More realistically, as anyone who knows children will testify, the object decides what it will eat on a case-to-case basis. A baby will eat coins, a toddler will only eat beans at Grandma's house, etc. Then we'd replace stuffItWillEat with a method, eatThis(Food) throws FoodAcrossTheRoomInAngerException. You could do that in one of three ways:

1. An abstract method in an abstract class. You couldn't implement a separate requirement in the same way unless you made the abstract class contain more than one method, because you don't have multiple inheritance. So you lose flexibility in relation to the next option, and gain nothing. You also start to program monolithically, because you're tempted to shove everything in one abstract class.

2. A method in an interface. This way works pretty well, with the slight annoyance that every time you want to make a new instance that differs slightly from another you need a new class. It's flexible; you can implement more than one interface, so it doesn't encourage you to put everything in one interface.

3. A concrete final class with a field holding a function that gets run when you want to find out whether the animal will eat something. This is my preferred option, because it results in the least code duplication and is the simplest.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
There are times, though, when one simply doesn't need that kind of flexibility.


Agreed. The interesting thing is that the simpler solution actually is the more flexible. It often works out that way. You overestimated the complexity of my approach earlier (see the bit about scrolling down, two posts ago).

I believe in the extreme programming principle of "build only what you need, and not what you think you might someday need".


Yes, YAGNI is very powerful, but DRY is more so. When evaluating a choice between two options that are of roughly equivalent complexity, such as how you probably see our two options here, given the fact that you've already measured complexity in lines of code, then YAGNI doesn't come into it. YAGNI means don't add stuff you don't need. It doesn't mean that because you know one technique, and it works, you don't need to learn other techniques. That is, don't apply YAGNI to your brain.

If I'm dealing with a complex process, and I'm writing a new extension to that process, I don't want to have to think about how every detail works, and have to rebuild it all.


Complex processes tend to have hooks to let you insert your own code. Doing it at undocumented places, not to say that you are doing, is a little risky. When you want to define what a button does when you click on it, you don't subclass it and override 'onClick', because in a complex process such as a GUI, you tend to want to do multiple things when a button is clicked.

If a complex process is written without hooks to let you insert your own code, then the designers probably didn't want you to insert your own code, or they assumed that you'd figure out how to do it by subclassing. So you figure it out and you do it differently to how they expect, then your code breaks with the next update. Directly exposing the hooks via things like addActionListener is a lot more robust than indirectly exposing them via things like paintComponent. Many programmers still override paint instead of paintComponent by accident..

it's a good thing that I'm "accidentally inheriting" behavior, because I don't want to be in a situation where I have to remember and deal with every detail of the process.


You don't have to remember every detail to be able to implement an ActionListener.

I guess what I'm saying is that when you say "all Abstract classes are bad", you're taking on a tremendous burden of proof


I'm saying that the concept is bad. I can only prove it empirically. Provide me some code that you think suits abstract classes, and I'll tell you why it doesn't. I'll pick an example now.

MouseListener. It has about 5 methods, most of which you're not interested in in a typical implementation, so hey presto, MouseAdapter exists. It implements those methods, making them do nothing.

When you subclass MouseAdapter, and misspell one of the methods, you get no compile warning/error (unless you're in the habit of using @Override).

A better approach would be, predictably, a builder.

MouseListenerBuilder.mouseClicked(someAnonymousClass).mousePressed(someAnonymousClass).mouseEntered(someAnonymousClass)..

Or not.

Perhaps it's worth looking at why MouseListener has 5 methods, and changing it so that it doesn't. If backward compatibility bothers you, imagine you can go back in time for the sake of this discussion.

MouseClickListener, MousePressListener, MouseEnteredListener, all as separate one-method interfaces.. But wait, the method in each has the same signature except the name! (mousePressed(MouseEvent event), etc.)

So, how about MouseEventProcedure, or Procedure<MouseEvent>, given generics, then you can do:


Now we don't have the monolithic MouseListener anymore. The design is better. I'm sure it could be improved further, but I don't know how, or why.

That's the kind of thinking and good design that you'll never reach if an abstract class is your default, and you're happy with it.
[ March 31, 2007: Message edited by: Ricky Clarkson ]
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Ricky,

While your pattern may be conceptually simple, and in a Utopian language may actually be simple, we're talking about Java. Yes, I did scroll down to your other example, but don't accept it as a viable option since all coding standards that I must adhere to in my daily work don't allow public properties.

As it happens, I already have the other artifacts ready in a library called functionalpeas.

Wonderful for you, but I don't. I'd have to build it. Do you have one that covers this method?

If not, you'd have to build one too.

As I said before, it's a great pattern! I like it, and will be using it more. However, in Java, coding this pattern takes more effort than coding a simple abstract class. To me, that's glaringly obvious, and I doubt you will ever convince me otherwise.
That's the kind of thinking and good design that you'll never reach if an abstract class is your default, and you're happy with it.

You misunderstand me. I think I've made it quite plain that an abstract class is not my default. If I see a need for flexibility, and can find a way to make it work with interfaces, that's my default. I readily agree that the abstract class is a tool with limited usefulness, but I don't think it's a useless tool. I generally don't throw tools out of my toolbox because they have limited uses (unless I have a really small toolbox!).

Provide me some code that you think suits abstract classes, and I'll tell you why it doesn't.


OK. I'll accept the challenge. You'll find my scenario at http://docs.google.com/Doc?id=dcgr77jt_2d967q8

The constraint I make is that I'm looking to "do the simplest thing that could possibly work" (DTSTTCPW)

I doubt it will resolve anything, though, because you and I seem to disagree about what is the simplest solution, or even what the definition of simple is. I say if you need an abstract inner class to do something, it can't be all that simple. If one solution needs 3 interfaces to make it work, and another just needs one concrete method, I'd say the one that just needs the concrete method is the simpler.

Going back to Pete Stein's response to one of your posts:
all generalizations are bad

While sweeping generalities like the ones you seem so fond of may be good for generating livelier forum discussions (and yours has certainly accomplished that goal!) They make for lousy policy, either personal or institutional.

I'll stick with the more boring, but more accurate qualified statements. The policy that I prefer to set for myself is the one stated by Joshua Bloch in his book Effective Java, which in my view is the bible of Java coding style:
Prefer interfaces to abstract classes

That, I can live with and agree with.
[ March 31, 2007: Message edited by: Merrill Higginson ]
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
While your pattern may be conceptually simple, and in a Utopian language may actually be simple, we're talking about Java.


The kind of complexity that anonymous inner classes add is very linear, and very localised. As I mentioned earlier, BGGA closures should alleviate most of the syntactic problems with the solutions I propose.

What it all boils down to is how you see an object. Here's the typical JavaScript view:

An object is a bag of properties, some of which may be functions.

And the typical Java view:

An object is an instance of a class, and a class can contain methods.

There is some halfway point, you can see a JavaScript object as an instance of a class if you like, but an unnamed, mutable class. In the same way, you can think of 3 as 1+1.5+0.5 if you like, but it gets you nowhere fast.

The JavaScript view of things is actually simpler, in that it doesn't encourage complex designs. In fact, because development environments (that I've seen) for JavaScript are so paltry, the importance of simplicity in design is heightened, though I'm not sure how many JavaScript developers appreciate that.

Yes, I did scroll down to your other example, but don't accept it as a viable option since all coding standards that I must adhere to in my daily work don't allow public properties.


Public fields, you mean. Java doesn't have properties. If it did, which I support, then those coding standards would be out of date. Public/private only really matters for API code; for code that's only used within one project/responsibility border, you may as well make everything public. I realise this sounds like heresy; such is the nature of debunkery. If refactoring could work across projects/continents, as I describe in this blog post, then the coding standard really would be generally wrong.

The first practical reason for making things private by default is so that you can later add setters/getters to control/log access, without changing clients. Properties would be a much better fit. The second is that modern IDEs can easily tell you when you aren't using a private method/field, but they don't tell you about public methods/fields so much. That's a temporary consideration, hopefully.

Of further interest is final fields. There is little good reason for making a final field private - it cannot be altered anyway, except by ridiculous tricks that wouldn't be thwarted by the private modifier anyway.

As it happens, I already have the other artifacts ready in a library called functionalpeas.


Wonderful for you, but I don't.


The library, functionalpeas, is freely downloadable via Google Code. The interface for a Function is tiny anyway.

Given your case of a method with a few parameters, the answer is Yes, by the power of generics, it is possible for a Function with one input and one output to represent the method you describe. E.g., a method like 'Double blah(String s,Integer i,Boolean b)' would look like Function<Pair<Pair<String,Integer>,Boolean>,Double>. I don't use this myself, at least not that I recall, and I wouldn't recommend it, but it is possible. Introducing variance (varargs) on generic type parameters would make this more palatable.

Oh, on the subject, functionalpeas doesn't cover exceptions, but you could write one that does. I don't write code that (deliberately!) throws exceptions in Java.

However, in Java, coding this pattern takes more effort than coding a simple abstract class.


Agreed, there is the discrepancy between complexity and apparent complexity to deal with. Writing the abstract class is at most half the battle. At least the other half is in writing the subclass. Then there's the problems caused when the superclass decides to add a method that the subclass already implements, etc. It's a shared namespace, there are problems inherent in that.

Ok, I had to make up some extra requirements to make the code worth writing, so here's the bare minimum, which alone doesn't make sense, followed by the version with extra requirements (some actual functionality that can be overridden, etc.):



and with the extras:



This was a bit challenging, because you wrote the problem spec around the idea of abstract classes, rather than taking a real problem. If this were a real problem, I'd go to its roots and take out the entry level programmers you mentioned; they'd cause more harm than good. Keeping this single responsibility means that you're willing to make a scapegoat out of an individual developer/architect; hardly the stuff great teams are made of.

I'd say it's a great way to increase staff turnover.

In the requirements, it was a bit vague how we define what a bank can do, even though we're not ourselves the bank.

While sweeping generalities like the ones you seem so fond of may be good for generating livelier forum discussions (and yours has certainly accomplished that goal!) They make for lousy policy, either personal or institutional.


Nah. Making an absolute statement, but not being proud, is a great way of hammering out an idea. Prejudice without pride, perhaps. If I express my idea in plain English, and you contradict it, intelligently, in plain English, then I'll know my idea was wrong immediately. If we dress the points up in flowery polite language (I'm not impolite, just direct, in general), then it takes a lot longer to get somewhere.

I always accept that there are people who know more than me, or are better than me, so I'm always open, and always thinking. I regularly listen to the opinions of people I completely disagree with; partly because I'm interested to hear why they have those opinions in the first place, and partly because there are sometimes good insights to be found there, or at least humour.

With abstract classes, I expect that your opinion originates in books and lecturers jumping on inheritance of behaviour as being the really big thing in OOP. When I used to help someone teach a Java course, students would automatically want to know what to extend, as if every class had to have an extends clause. I even saw students add 'extends JPanel', etc., even when their programs weren't graphical..
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
Originally posted by Ricky Clarkson:


Really? You can write procedural code and comply with that, if you say that every procedure is an instance of a class.


By saying that we should visualize every problem as Objects in real world I meant about the actors in the problem.And about the prodedure ,that again should be in object that its related to.Then there can be a class with main method for having the logic to make use of the constructed objects to solve the problem.

If OO paragdim doesn't say to visulaize a problem in terms to objects then what does OO advocates for ?


Originally posted by Ricky Clarkson:


Human is a subclass of Omnivore, possibly indirectly via Mammal, etc. However, my ex-girlfriend, Jenny, is an instance of a subclass of Human (no offence meant to her), but is not an Omnivore. She is a Vegetarian.



For the above , you are going to0 deep the inheretence tree.Then one may again want to compose a human with various objects like hands, legs , head ect.(One should do this if the prime object to focus in the problem is human.)So , things would keep on extending and there is no end to that.Moving forward one might want to compose a hand object using various cells.So to my best of knowledge designing a inheritence tree so deep is not of any use if the prime object in the problem is various animals.
[ April 01, 2007: Message edited by: Rahul Bhattacharjee ]
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
And about the prodedure ,that again should be in object that its related to.


What if it relates to 2 objects? Or no objects?

If OO paragdim doesn't say to visulaize a problem in terms to objects then what does OO advocates for ?


In more OO languages than Java, procedures are objects too. I think your book/lecturer tells you to visualise problems in terms of nouns, not objects in general. I suggest you read about the Kingdom of Nouns.

For the above , you are going to0 deep the inheretence tree.


You only say that because I pointed out a case that doesn't fit in the inheritance tree. If I'd said Human extends Omnivore extends Animal, and not mentioned Jenny, you'd probably be happy.

When would you find out about Jenny in your project? I'd guess towards the end. What would you do? Redesign the inheritance tree, or slap a quick hack on that allows Jenny to throw an UnsupportedOperationException when you ask her to eat meat? If you don't go for monolithic supertypes, it's easy to solve.
Rahul Bhattacharjee
Ranch Hand

Joined: Nov 29, 2005
Posts: 2308
Originally posted by Ricky Clarkson:


What if it relates to 2 objects? Or no objects?


Then it should go to the common class , might be a helper / util class.


Originally posted by Ricky Clarkson:


In more OO languages than Java, procedures are objects too. I think your book/lecturer tells you to visualise problems in terms of nouns, not objects in general. I suggest you read about the Kingdom of Nouns.



I agree with you.

Originally posted by Ricky Clarkson:

You only say that because I pointed out a case that doesn't fit in the inheritance tree. If I'd said Human extends Omnivore extends Animal, and not mentioned Jenny, you'd probably be happy.



In that case there cannot be any perfect inheretence tree , I am sure if you go too deep the tree , you would definately find a need to change the inheritence tree.
Can someone give an example of a perfect inheretence tree , that would in no condition have the need to refractor at any point of time in future ?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: about abstract class