Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
For a few years I was a teaching assistant for an introduction to programming module - Java for first year undergraduates.
Mostly it went well and we managed to get object-oriented programming across to the students quite well, but one thing that students rarely saw the point of was interfaces.
Pretty much any explanation we gave either came across as too contrived to be useful for learning, or too far removed from their position as beginners. The reaction we tended to get was "I... see," translated as "I don't understand and they don't sound useful".
Anyone here have a way of successfully teaching students about interfaces? I'm not a teaching assistant any more, but it's always nagged at me.
If you are trying to explain it to beginners I would stick with the idea that interfaces can promote code reuse and modularity within the code:
For example lets say we are going to paint some objects:
public class Painter {
private List<Paintable> paintableObjects;
public Painter(){
paintableObjects = new ArrayList<Paintable>();
}
public void paintAllObjects(){
for(Paintable paintable : paintableObjects){
paintable.paint();
}
}
}
public interface Paintable {
public void paint();
}
Now you could explain to the students that without Paintable interface the Painter object would need to have methods to paint certain types of objects, like a method called paintFences() and paintRocks() and we would need to have a new Collection for each type of objects we want the painter to be able to paint.
But thankfully we have interfaces which make painting objects a breeze and how objects are painted is left entirely up to classes that implement the Paintable interface.
EDIT
Another benefit that I forgot to mention is that if you ever need to add new object to paint to your code base, all you need to do is create a new class that implements Paintable and the Painter class never has to change. In this sense the Painter class is never dependent upon the objects it is going to paint, it only needs to be able to paint them.
EDIT 2
James Raybould reminded me of a key use of interfaces I forgot to mention: Having an interface between your components, like the Paintable objects and Painter objects, allows you to more easily develop with other people. One developer can work on the Painter objects and another can work on the Paintable objects and all they have to do to function properly together is define a common interface beforehand that they will both use. I know when I've worked on projects with other people in college level projects its really helpful when you are trying to have everyone work on different parts of the project and still have all components come together nicely in the end.
In explaining interfaces and object oriented concepts in general to non-programmers, I always use the home entertainment system analogy.
The DVD player, TV, Cable Box, Remote Control are all objects that encapsulate complicated and sophisticated functionality. However, they have interfaces to each other and to the Humans that operate them that largely hide the lion share of that complexity.
The video in jack of a TV is an interface that is implemented by the DVD player and the cable box and a number of other types of devices.
I suspect it would be possible and perhaps an educational exercise for a student to describe their own home entertainment system entirely using Java code.
"Where classes ARE something, typically interfaces DO something. So I might have a car, but I would never go "carring" but I might go driving... so my Car might implement "drivable" interface."
EDIT:
Mark brings up a good point. Interfaces don't do anything at all, but instead define what behaviors happen. And, he also brings up a good point about not wanting to confuse the audience. Not that it's okay to confuse seasoned developers, but it's definitely not a good idea to confuse a brand new student. In light of this, I'm revising my one-liner into a many-liner.
"Where classes define existence, interfaces define behavior. Classes define what something is, while interfaces define what something does. So I might have a car, and it has things like an Engine, how much gas it has, what it's historic MPG is, and the like, but I would never go "carring". I might, on the other hand, go Driving... can my Car drive? It can if I give it a Drive method. I can also have "Driveable" interface with a drive method, and leave it up to the car to determine what driving really means. Now, if I only have cars it's not a big deal to have an interface. But what about trucks? If they both are Drivable, I can simply have a List<Drivable for both of them. Of course, the observant student says "Why can't Car and Truck both simply extend Vehicle, with an abstract Drive method?" Which, actually is a very valid notion. But, what about the Space Shuttle? Very few of the components between Car and Truck apply to the Space Shuttle, so it doesn't seem well suited to extend the Vehicle class. Or what about future cars? We have no idea what they might be like, they might not have chassises, they might just be bubbles of energy that move us around, but we might still call their behavior drive()."
breathes
Now that paragraph/essay is a little verbose, but I could see, with some slides or a chalkboard, being effective for first year students to get their head around (assuming they understand abstract classes first anyway).
Well I just explained interfaces to a work partner, she was learning java from progress and she really did not get all the OOP stuff at the beginning so I just explained everything from a non-software engineering point of view, my explanation for interfaces where something like this:
Suppose you want to hire a plumber to fix some things on your house, you don't know (and you don't care much) who you may end up hiring but you know what the plumber must be able to do. So, you define a set of tasks that anyone that claims to be a plumber must know how to do. Of course everybody might have its own way of carrying out each task, but in the end, the person you are hiring is a plumber because they know how to do each task. So, if you were to write this in java, the first thing to do would be to define an interface plumber like this:
public interface Plumber
{ //silly code here }
OK then, let's say that I know how to do each task you are requesting for and so I'm fully compliant with your requirements and so according to you I'm a plumber. So, today I decide to be your plumber and you decide to hire me (yay!), based on the last example, you can say that I'm a person that knows how to develop software and plumbing in a specific way, if I were to write code for me as a class I could write something like this:
public class Rick extends Person implements SoftwareDeveloper, Plumber
and later you could fix things in your house using me as your plumber:
Plumber thePlumber = rick;
thePlumber.fixLeak(myHouse.bathroom.leak) // =(
from this point on, the remaining OOP concepts were easy to explain.
Well, recently, I happened to explain this to someone close. The way I explained the question "why Interfaces?", is by taking example of of the USB Port and the USB drives.
The USB port can be considered as a specification, and any USB drive can fit into it, provided they implement the specification. So in this case, the port becomes the Interface and the numerous types of USB sticks available, become the class.
Carrying this example ahead, if I were to supply someone an USB drive (class), I would not need to tell them (the calling method) as to what am I passing across. Had the calling method taken a USB drive (class type) as a reference, I would not have been able to pass any but only the USB drive that the port is meant for.
To sum it up, Intefaces, help the caller be comptabile with the calling method (in a use-case when the calling method expects an instance of a particular type), no matter what instance you pass across, the caller as well as the callee are sure that it (instance) would fit into the Interface reference (the USB port for analogy).
Class, we spent the last few sessions implementing quicksort. It was difficult to sort that list of Persons by name. What would you now do, if you had to sort this list by grade? And what would you do if you had to sort a list of dinousaurs by age? The only way you know so far is to copy the code of the quicksort, and change the comparison and the types it operates on. That would work - until you find that elusive bug that always plagued your quicksort, and had to fix it in several dozen copies of that quicksort scattered all over the place.
Today, we are going to learn a better way.
We can write a quicksort without defining the order we want to sort the list into, and define that order (and only that order) separately when we invoke that quicksort.
[ insert explanation of the mechanics of interfaces and polymorphism, using the Comparator interface as example, here ]
Now, there is only a single copy of quicksort, and bugs only have to be fixed once. Also, people can use quicksort without understanding it (or if they have understood it, without thinking about its mechanics whenever you want to sort something). Also, the people writing the quicksort did not need to know the order you need your list sorted. So the interface isolated the two groups of programmers, allowing them to develop their parts of the software in isolation. This is why, in many programming languages, you will find well implemented and tested sort methods in the api, even though the programmers of these methods could not know all the types of objects and orders people want to sort into later.
I usually use "contract" but "promises solemnly to provide" might also help understanding.
I recommend the first chapter of Head First Design Patterns for this. The Duck simulation explains the problem with using inheritance, and the rest of the chapter goes on explaining how to do it.
This explains best : (referenced from this tutorial)
There are a number of situations in software engineering when it is important for disparate groups of programmers to agree to a "contract" that spells out how their software interacts. Each group should be able to write their code without any knowledge of how the other group's code is written. Generally speaking, interfaces are such contracts.
For example, imagine a futuristic society where computer-controlled robotic cars transport passengers through city streets without a human operator. Automobile manufacturers write software (Java, of course) that operates the automobile—stop, start, accelerate, turn left, and so forth. Another industrial group, electronic guidance instrument manufacturers, make computer systems that receive GPS (Global Positioning System) position data and wireless transmission of traffic conditions and use that information to drive the car.
The auto manufacturers must publish an industry-standard interface that spells out in detail what methods can be invoked to make the car move (any car, from any manufacturer). The guidance manufacturers can then write software that invokes the methods described in the interface to command the car. Neither industrial group needs to know how the other group's software is implemented. In fact, each group considers its software highly proprietary and reserves the right to modify it at any time, as long as it continues to adhere to the published interface.
More Link: http://download-llnw.oracle.com/javase/tutorial/java/concepts/interface.html
Understanding interfaces is not very different to understanding polymorphism and IS-A relationships. All classes implementing the same interface can be manipulated uniformly by the program as the "base" type because of the relationship established by implementing an interface or inheriting a base class.
The choice between an interface and a base class is a design decision. I'd keep this simple.
Define a class when your implementation can assume the complete or partial behavior of a class.
Make that class abstract to indicate the base class is not a complete implementation and cannot be used as is.
Provide an interface instead of a base class if it does not make sense to provide a partial implementation.
The benefits of interfaces and inheritance are pretty much the same. An interface is simply a more abstract definition of a type than a base class is.
Update
Here's a simple program you could use to demonstrate how similar inheritance and interfaces are. Modify the program to make Base an interface instead of a class. In ClassA, replace "extends" for "implements". The program's result will be the same.
The purpose of ClassB is to illustrate further illustrate the importance of the relationship between a class and its interface/base class. An instance of ClassB may not be passed to processBase in spite of its similarities with Base, unless we establish an explicit relationship.
abstract class Base {
public void behavior() {};
};
class ClassA extends Base {
public void behavior() {
System.out.println("ClassA implementation of Base behavior");
}
};
class ClassB {
public void behavior() {
System.out.println("ClassB's version of behavior");
}
}
public class InterfaceExample {
public void processBase (Base i) {
i.behavior();
}
public static void main (String args[]) {
InterfaceExample example = new InterfaceExample();
example.processBase(new ClassA());
}
}
Interface Oriented Design describes this better than I ever could http://pragprog.com/titles/kpiod/interface-oriented-design. The author uses some excellent examples of interfaces versus inheritance for things like the taxonomy of the animal kingdom. It has some of the best arguments against excessive inheritance and judicious use of interfaces I have read to date.
A bunch of websites with incompatible ways of bringing them up:
Listing of Facebook.java:
public class Facebook {
public void showFacebook() {
// ...
}
}
Listing of YouTube.java:
public class YouTube {
public void showYouTube() {
// ...
}
}
Listing of StackOverflow.java:
public class StackOverflow {
public void showStackOverflow() {
// ...
}
}
A client manually handling the different methods the websites use to bring
themselves up:
Listing of ClientWithoutInterface.java:
public class ClientWithoutInterface {
public static void main(String... args) {
String websiteRequested = args[0];
if ("facebook".equals(websiteRequested)) {
new Facebook().showFacebook();
} else if ("youtube".equals(websiteRequested)) {
new YouTube().showYouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
new StackOverflow().showStackOverflow();
}
}
}
Introduce a Website interface to make the client's job easier:
Listing of Website.java:
public interface Website {
void showWebsite();
}
Listing of Facebook.java:
public class Facebook implements Website {
public void showWebsite() {
// ...
}
}
Listing of YouTube.java:
public class YouTube implements Website {
public void showWebsite() {
// ...
}
}
Listing of StackOverflow.java:
public class StackOverflow implements Website {
public void showWebsite() {
// ...
}
}
Listing of ClientWithInterface.java:
public class ClientWithInterface {
public static void main(String... args) {
String websiteRequested = args[0];
Website website;
if ("facebook".equals(websiteRequested)) {
website = new Facebook();
} else if ("youtube".equals(websiteRequested)) {
website = new YouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
website = new StackOverflow();
}
website.showWebsite();
}
}
Whoop-de-doo, more code for nothing? Actually we can go a little further and
have the client rope a couple of friends into helping it find and render a
requested website:
Listing of ClientWithALittleHelpFromFriends.java:
public class ClientWithALittleHelpFromFriends {
public static void main(String... args) {
WebsiteFinder finder = new WebsiteFinder();
WebsiteRenderer renderer = new WebsiteRenderer();
renderer.render(finder.findWebsite(args[0]));
}
}
Listing of WebsiteFinder.java:
public class WebsiteFinder {
public Website findWebsite(String websiteRequested) {
if ("facebook".equals(websiteRequested)) {
return new Facebook();
} else if ("youtube".equals(websiteRequested)) {
return new YouTube();
} else if ("stackoverflow".equals(websiteRequested)) {
return new StackOverflow();
}
}
}
Listing of WebsiteRenderer.java:
public class WebsiteRenderer {
public void render(Website website) {
website.showWebsite();
}
}
Looking back at ClientWithoutInterface, it is totally coupled to both specific lookup and rendering based. It would be very difficult to manage when you get to hundreds or thousands of sites. With the Website interface in place the WebsiteFinder could easily be converted to be backed on a Map, a database or even a web based lookup to satisfy increasing scale.
Interfaces make it possible to separate a role from the component that achieves it. They make it possible to swap in alternative solutions to the same problem based on pretty much anything:
Current load on machine
Size of the data set (sorting algorithms can be picked)
User requesting the action being performed
I was typing this as a comment to Harima555s answer, but it expanded. I wondered if it makes more sense to start at the other end - give them a feel for how interfaces are useful, before going into how you write one.
Presuming they have a good grasp of inheritance, polymorphism and abstract classes. I would probably start with a recap on abstract classes, by asking one of the students to explain them.
Next, introduce an example of classes with interfaces to get over the concept of roles / contracts. To simplify things, start with a single superclass.
public class Rick extends Person implements SoftwareDeveloper, Plumber
public class Zoe extends Person implements SoftwareDeveloper, Chef
public class Paul extends Person implements Plumber, Chef
public class Lisa extends Person implements Plumber
Don't explain it too much, but try and get the student to work through what the syntax might mean - perhaps showing some code that references a Plumber or SoftwareDeveloper.
Ask them how they would achieve the same thing using inheritance from Person. They should get stuck quite quickly, or come up with multiple inheritance. To avoid discussing the diamond problem until later, say there are no overlapping methods in the roles.
Next I'd try to get over the idea that the same interface can be used on different types of Class.
public class Plane extends Vehicle implements Fly, PassengerTransport, Serviceable
public class Train extends Vehicle implements PassengerTransport, Serviceable
public class Bird extends Animal implements Fly
Again, try to get them to consider how they could implement the same thing using a common superclass and overrides.
Then illustrate how you would write polymorphic code using the interface rather than class - say a TravelAgent who sells tickets for a PassengerTransport. Dwell on the strength of this - that you can write polymorphic code that works on Classes from different hierarchies.
At this point, they should probably be under the illusion that an interface is a pretty much like being able to add another superclass to a class, and will have grasped the advantages of multiple inheritance.
So now we have to explain why that complicates things, and interfaces have no default implementation, via understanding the diamond problem.
Go back to the first example, get them to work through what happens if SoftwareDeveloper and Plumber both have a 'MakeDrink' method (one makes Cola, the other makes Coffee) and we execute MakeDrink on Rick.
Try and nudge someone towards considering the idea that if MakeDrink is kept abstract in both 'superclasses' the problem goes away. At this point, having got the conceptual side, we should be ready to cover the syntax for defining an interface.
(I did consider introducing the second reason - the difficulty of writing generic code that could be applied to different class hierarchies, but found that you end up with 'well why can't you inherit an altitude attribute from the interface' or discussing generic programming too early).
I think by now we should have covered the concepts via the mickey mouse examples - and you could then go back through explaining the correct technical terminology, and use real-world examples from the Java API.
I wouldn't want to confuse people while they are trying to learn Java/Interfaces, but once they've got it, it may be worth pointing out that other OO languages take different approaches to the same problem, from multiple inheritance to duck-typing - and if they are interested they should research them.
Do you teach JDBC as well? Take it as an example. It's an excellent real world example of how powerful interfaces are. In JDBC you're writing code against an API which exist of almost only interfaces. The JDBC driver is the concrete implementation. You can easily reuse the JDBC code on many DB's without rewriting the code. You just have to switch the JDBC driver implementation JAR file and driver class name to get it to work on another DB.
At least, using interfaces offers you the possibility to change from the concrete implementation (the code logic which is responsible for the behaviour) at some way/point without rewriting the whole code. Try to use real world examples when explaining things. It would make more sense.
Well, I found lately a very useful method of using interface.
We have many objects...
public class Settings { String[] keys; int values; }
public class Car { Engine engine; int value; }
public class Surface { int power; int elseInt; }
// and maaany more (dozens...)
Now, someone is creating (i.e.) table and want to show some of objects from the list of all objects, but to show objects in the list he must write method that returns String[].
String[] toArrayString()
So he just implements this method in all classes that he need to in table
public class Settings { String[] keys; int values; public String[] toArrayString {...} }
public class Car { Engine engine; int value; } // THIS NOT
public class Surface { int power; int elseInt; public String[] toArrayString {...} }
// and maaany more (dozens...)
Now, when he creates table he is writing smth like this
public void createTable() {
for(Object obj : allObjects) {
if(obj instanceof Settings) {
Settings settings = (Settings)obj;
table.add(settings.toArrayString());
}
if(obj instanceof Surface) {
// cast...
}
// etc multiple times...
}
}
With interface this code can be much shorter and easier to read and maintain:
public interface ISimpleInterface { String[] toArrayString; }
public class Settings implements ISimpleInterface { String[] keys; int values; public String[] toArrayString {...} }
public class Car { Engine engine; int value; } // THIS NOT
public class Surface implements ISimpleInterface { int power; int elseInt; public String[] toArrayString {...} }
public void createTable() {
for(Object obj : allObjects) {
if(obj instanceof ISimpleInterface) {
ISimpleInterface simple = (ISimpleInterface)obj;
table.add(simple.toArrayString());
}
}
}
Moreover, we can implement multiple interfaces in a very clean and effective way without any derivation (derivation is sometimes impossible and not only in case, when class is using some kind of other derivation already).
Interfaces provide a look at what a class needs to do for instance you can have an Animal interface and lets say that has a method called speak(), well each animal can speak but they all do it differently but this allows you to cast anything that implements animal to animal so you can have a List of animals and make them all speak but use their own implementation. Interfaces are simply wrappers for these kinds of things.
In this previous question there are some good scenarios that explain the whys behind the use of interfaces.
Stack Overflow Question
The real value of interfaces comes with being able to override components in 3rd party APIs or frameworks. I would construct an assignment where the students need to override functionality in a pre-built library that they cannot change (and do not have the source for).
To be more concrete, let's say you have a "framework" that generates an HTML page implemented as a Page class. And page.render(stream) generates the html. Let's say that Page takes an instance of the sealed ButtonTemplate class. The ButtonTemplate object has its own render method so that in page.render(stream) buttonTemplate.render(label,stream) gets called anywhere there is a button and it produces the html for a submit button. As an example to the students, let's say that we want to replace those submit buttons with links.
I wouldn't give them much direction other than describing the final output. They will have to pound their heads trying various solutions. "Should we try to parse out the button tags and replace with anchor tags? Can we subclass ButtonTemplate to do what we want? Oh, wait. It's sealed! What were they thinking when they sealed this class!?!" Then after that assignment show a second framework with the ILabeledTemplate interface with the render(label,stream) method.
In addition to the other answers, you could try explaining it from a different perspective. The students I'm sure already know about inheritance because it is jammed down the throats of every Java student from probably lecture one. Have they heard about multiple inheritance? Method resolution was seen as a design issue in C++ (and also in Perl and other multiple-inheritance languages) because conceptually it's ambiguous as to exactly what should happen when a method is called in a subclass that is defined in two of its base classes. Are both executed? Which one goes first? Can one be referenced specifically? See also the diamond problem. It's my understanding that this confusion was resolved simply by introducing interfaces, which have no implementation, so there's no ambiguity as to which implementation to use during method resolution.
If a class needed to handle exactly one piece of abstract functionality, and didn't need to inherit any other class, one could use an abstract class to expose the functionality and then derive the real class from that. Notice the two items in italics, however. Interfaces make it possible for a class to behave as several independent types of abstract things, even if the class is derived from another class that does not behave as those types of things. Thus, interfaces satisfy one of the main usage cases for multiple inheritance, without the ickiness that goes along with multiple inheritance.
A simple real-world example of a very practical interface: iEnumerable. If a class holds some arbitrary number of some type of item, is is very useful for another class to act upon all of those item without having to worry about the particulars of the object that holds them. If "enumerableThing" were an abstract class, it would be impossible for an object of any class which derived from something that wasn't an "enumerableThing" to be passed to code that expected an enumerableThing. Since any class, including derived classes, can implement enumerableThing without regard for whether the base classes do so, it's possible to add enumeration ability to any class.
A long time ago, I read a book (can't remember the name of it though) and it had a pretty good analogy for interfaces. If you (or your students) ever went to a Cold Stone Creamery ice cream store, this will sound kind of familiar. Cold Stone has ice cream and with the ice cream you can add several different things to the ice cream (called mix-ins at Cold Stone). These mix-ins would be analogous to interfaces. Your class (or ice cream) can have as many interfaces (or mix-ins) as you want. Adding an interface (or mix-in) will add the contents (or flavor) of that interface (or mix-in) to your class (or ice cream). Hope this helps!
Contracts are first things that are taught about interfaces but they are built in the language to provide the skills of multiple inheritance and avoid the complexity of multiple inheritance.. So you can teach them that interfaces add runtime behaviour to programs, or you can tell the students that interfaces can be used to change runtime behaviour of objects..
First, the students must grasp the concept of abstractions.
When you (you == the students) see a teacher, you can describe him as a teacher...
You can also describe him as an employe (of the school).
And you can describe him as a person.
You will be right the three times. Thoses are "titles" you can give him.
He is a teacher, a computer science teacher, in the same way a math teacher is a teacher.
They are on the same level of abstraction.
Now a teacher is an employee, in the same way a janitor is an employee.
They are on the same level of abstraction.
An employe is a person, in the same way an unemployed person is a person.
They are on the same level of abstraction.
(Draw the whole thing on the board in a UML kinda way).
And that's the architecture that will describe (roughly) the position of a science teacher in society.
Now the levels of abstraction define what a common group of objects have in common : All the teachers teach to their students and create impossible exam questions to make sure they fail. All the school's employes work for the school.
In programming, an interface is a level of abstraction. It describes the actions that a group of objects can accomplish.
Each object has a unique way of doing the action, but the type of action is the same.
Take a few music instruments for example : A piano, a guitar and a flute.
What do they have in common ? A musician can play them.
You can't ask a musician to blow in the 3 instruments but you can ask him to play them.
The architecture of the whole concept will be the following:
The Interface (what they have in common) is Instrument. Because they're all instruments : it's an abstraction they all have in common.
What can they do in common ? Play. So you define an abstract method called Play.
Now you can't define how the "Instrument" will play because it depends on the type of instrument.
Flute is a type of Instrument. So the class Flute implements Instrument.
Now you must define what the musician will do when he plays that type of instrument.
So you define the play method. This definition will override the definition of the Instrument.
Do the same with the 2 others instruments.
Now if you have a list of instruments but don't know what type they are, you can still "ask" them to play.
Each flute will be blown.
Each guitar will be scratched.
Each pianio will be ... huh... pianoted ? whatever !
But each object will know what to do to execute the action "Play". You don't know what kind of instrument they are, but since you know they are instruments, you ask them to play and they know how to do that.
You may also want to compare and contrast interfaces in Java with C++ (where you end up using multiple inheritance and/or "friend" classes).
(At least, to me, that showed me how much simpler/easier interfaces were in Java :-)
I would tell them "Interfaces define what behaviors are provided" and "Implementations provide those behaviors". A piece of code that uses an interface doesn't need the details of how things are happening, it only needs to know what things can happen.
A good example is the DAO pattern. It defines behavior like "save", "load", "delete". You could have an implementation that works with a DB, and an implementation that goes to the file system.
I think a lot of the other answers so far are too complicated for students who don't get it right away...
I think in general, hands-on learning always helps reinforce concepts after lectures and examples. So in the same vein as meriton suggests, I would present two versions of the same program. (quicksort is a good example)
Have the students modify each program several times, unveil subtle bugs in the program for them to fix. Your students will soon find, I think, that interfaces provide many advantages when designing a program when they're the ones who have to modify it later!
I always think of it as a mean to (verbally) communicate as little as possible because that (good communication) is the most difficult thing in software engineering. Same for Web Services and SOA. If you give somebody an interface and say "Please provide me this service." it is a very convenient way because you don't have to explain a lot, and the compiler will check if they did a proper job, instead of you! (I mean, not really but at least it'll ensure the methods are there).
Related
I would like to know if it safe and a good practice to keep common code in a separate class and make method static.
I have a class Car, that is constructed based on inputs from other classes. I need to apply some post construct processing after the Car object is created. Example below.
Class Travel uses Car and calls postConstructProcessing method.
CarProcessor is simillary used in other classes whenever car object is creates.
My question is should I make method process Static in CarProcessor.
Class car{
Type type;
Int model
Car(Type t, int m){
...
...
}
;
....
...}
Below class of code uses Car and calls postConstructProcessing method
public class Travel {
public void go(){
....
....
Car c = new Car(t,m);
new CarProcessor().process(c);
}
}
class CarProcessor{
public Car process(Car c){
If(c.type.value.equals("ABC"){
c.type.version=1.1;
}
if(c.model=5.7){
c.price=50k
}
}
}
My question is , is it safe and a good practice to make method process in CarProcessor static.
In general it's not great.
The most obvious problem is, if you are testing the go method, how do you replace/mock out CarProcessor::process?
The real problem is organizational though. When you are coding next time and looking for the functionality you'd expect to see in "Car" or "go", you type "car." or "go." into your IDE and hit ctrl-space, you'd expect to see all the interesting methods shown to you. How do you know to create a CarProcessor to proceed?
Some things are difficult to implement in OO though--in particular utilities. Look at the entire Math package in the java library. It's full of static methods that you just call. An oo fanatic would say these all belong in the Number class (maybe something like "Number.math.sqrt()?", but java didn't take that route--in fact they don't even have a good common number class (We have one, it's not good)--
But even when we have real classes like String, we lean towards "StringUtil" and such. This has led to a HUGE number of conflicting "Util" implementations of String. In this case part of the problem is that String is immutable and we can't really back-fill it with methods (probably a good thing). but in general, OO just isn't great for general-purpose utility methods.
Functions (which is what you are proposing) are not awesome, but are heavily used. If you have the ability to modify your business classes then that's almost always a better fit for this type of code.
Just to clarify: A Function is different from a Method--methods work on members (class variables), functions are stand-alone (Might as well be static).
Functions are a very old approach at organization. OO is a somewhat newer approach invented for when the sheer number of functions become too difficult to manage (conceptually).
I posted a question about interfaces and advice I read about in Effective Java. I got the answer I wanted, and all was good, until this afternoon when I signed into SO, and a comment was left saying
These interfaces should not inherit from each other.
I asked why, but still haven't received an answer. Can someone explain why you wouldn't allow these interfaces to inherit? How would you fix it, and still keep the same functionality provided in the answer?
public interface GameObject {
void viewDetails();
}
public interface Weapon extends GameObject {
void attack();
}
//A weapon is not the only item reloadable. A container could be refilled.
public interface Reloadable extends GameObject {
void replenish (final int amount);
}
The only reason I see for these interfaces not to inherit, is the simplicity of the GameObject interface. It isn't providing any functionality that toString can't accomplish. However, it's only the beginning stages of my game, and GameObject will of course expand.
I think you are worried too much about the purity of your design, to the point where you are concerned with trifling details instead of spending your time productively, that is, writing your game.
Either way does not make much of a difference.
Usually, a "GameObject" (and anything whose name ends with "Object") is a class, abstract if need be, but not an interface. The only reason for naming an interface "SomethingObject" is if the interface also extends (or exposes by aggregation) the Closeable (AutoCloseable) interface, meaning that anyone who has a reference to it may destroy it. So, if you take this route, the rest of your questions are answered trivially: interface Weapon may not extend GameObject, because interfaces may not extend classes, and the same goes for Reloadable, and we are done.
Now, if you insist on having a "GameObject" interface, you still have the option of either extending it for every single additional characteristic, or keeping each additional characteristic separate, without extending "GameObject". Both approaches will work.
If you promise, if you swear in the name of everything that is dear to you, that there will never be a Reloadable which is not also a GameObject, then you can go ahead and have Reloadable extend GameObject. But do you really need that? The common practice is that we prefer using interfaces to increase the degree of branching of our inheritance tree, not to turn our inheritance tree into a graph. (Not that it never happens, but it happens very rarely.) So, we usually do not do that. But if you do that, it is not the end of the world.
Also note that when we extend one interface from another, we (not always, but) usually extend the names. So, your Weapon would be WeaponGameObject and your Reloadable would be ReloadableGameObject.
Also note that interface inheritance is rarely, if ever, necessary; you can make Reloadable a free-standing interface (that does not extend GameObject) and you can have Reloadable include a GameObject getGameObject() method, thus essentially linking the two entities together. Then, your BFG9000ReloadableGameObject class may implement both Reloadable and GameObject and implement getGameObject() as return this;
Do a real domain analysis. You'll find that something with replenish behavior, a Replenishable, needn't be a Weapon and may not care while replenishing that it's a GameItem. A Vehicle might also need replenishment. Perhaps something like
public interface Weapon extends GameItem {
public class ChargeGun
implements Replenishable, Weapon {...
public class FlyingCarpet extends GameItem
implements Replenishable, Vehicle {...
It's usually better to have a class do interface mixins than interfaces inherit them. It depends on the domain and how you model it. As much as feasible you want
gun.replenish();
not
replenish(Replenishable Replenishable);
YMMV.
Agreeing with Mike here: Probably not the stage you should be worried about this.
For game development modeling the 'world' using object-oriented principles is often avoided. This is due strong coupling of objects and performance reasons. Very advanced game engines don't create specific classes for entities in the world.
If you are interested in the finer details,
check this out:
http://entity-systems-wiki.t-machine.org/
Object oriented design is a pretty neat concept, but I'm struggling on how to wrap my head around most of its facets. I think the key to a good object oriented design is having a good grasp on how to look at it. I usually look at object-oriented this way:
Classes are Real-world entities or objects
Instance Fields are entity's attributes, ('has A')
Methods are like actions, verbs, Entity's abilities
Interfaces are like abilities that you can imbue on an object. It could also be an 'is A or can do' relationship whose implementations are not set in stone. Superman is a Krypton, being a Kryptonian comes with a set of special abilities, like flying, freeze-breath, etc. Superman fly different from Green Lantern and Goku and especially Batman, that is why Flight as interface is probably a good idea if you're creating a Fictional Universe.
public class SuperMan extends Man implements Kryptonian{}
public interface Kryptonian extends Flight, FreezeBreath{
public void fly();
public void coolBreath();
}
Problem comes along when you add Generics into the mix? Because the given type parameters somehow creates a contract between the class/interface and the type.
public interface Flight<T>{
public void fly(T t);
}
In this example, Flight is coupled with a T, T could be a superhero a bird or anything that can fly.But is that really how I should imagine it? Because that seems like the same as what plain interfaces do? Although, a parameterized interface is still an interface, the coupling with the type T is what really bothers me. Moreover, things also get complicated when you add bounded restriction on the parameter type.
public class Pidgey<T extends Bird> implements Flight<T>{}
what real-world concrete object can you identify T with? The above example is pretty wrong, although using the class parameter to also restrict the type of Flight is probably a good design, because Flight is still independent enough that other classes could still use it without any restriction. But the example itself is wrong. Pidgey is a Bird that can fly, but what what could T be? Well, T could be anything, it could be another object or abilities. The question is what are its implications, why put T there? What are real-world examples of doing so?
It's easy to understand when you talk about collections, since collections are like containers. You can create a wide variety of containers that holds different kinds of objects.
public class WaterBottle<T extends Liquid> implements UniqueCap{}
But I've seen Generics being used not just on a container-like objects? How could one design such objects, what did they consider?
Your analogies to the various features in OOP are definitely valid. Generics definitely make the most sense when talking about collections/containers/Hashmaps. They do have their uses in other places, though. For example, if a bank wants to process notes in many currencies, they can write
public class moneyProcessor
However, generics aren't required. In the context of your Flight interface, there wouldn't be much of a reason to use generics. Which brings me to another point:
Just because someone else does something one way doesn't mean you have to do it that way. OOP is very flexible for a reason. There's always more than one correct way. If a method takes an Object as a parameter, it's not the end of the world. Just make sure you can read it later. :)
Edit: and that others can read it too.
Its convention to use T when dealing with generics. it makes code readable as others reading your code will immediately know you're referring to a generic and nothing specific
I have come across few definitions over the years, and have never able to clearly understand what abstraction is.
I have understood the 3 main concepts of Oops but have had difficulties with this particular concept which is engraved within these other concepts.
Till now i have come to 2 conclusions, but not sure.
It is the ability to hide the implementation details of a method(Behavior), and provide the user with just the interface.
It is ability to define a method signatures(ie. only to declare them) without actually implementing them.
Which is the correct definition of abstraction with context to Object oriented programming, and if not one of the above, then what is it?
Would appreciate if supporting code is also provided :)
It is the ability to hide the implementation details of a method(Behavior), and provide the user with just the interface.
Sort of, but that's "encapsulation". They're related in the sense that "encapsulation" is a key concept of object oriented design whereas "abstraction" is a potential result of that concept.
It is ability to define a method signatures(ie. only to declare them) without actually implementing them.
That's an implementation detail, not the conceptual notion of abstraction itself.
In a simple inheritance model, "abstraction" can be thought of as referring to an object by one of its ancestor (or more abstract) types. For example, consider a hierarchy:
Lifeform
Animal
Canine
Golden Retriever
If you're performing an operation specific only to a Golden Retriever, then you can't perform that operation on any Animal. It has to be a specific Animal. So you need that specific implementation.
However, if you're performing an operation that's generic to all Lifeforms then it doesn't matter what specific implementation you receive. That operation is abstracted so that it can accept any Lifeform object, regardless of the more specific implementation.
Interfaces provide another implementation mechanism which can achieve abstractions. Object composition is still another mechanism. For example, consider this non-inheritance scenario:
public class MyObject {
private ThirdPartyObject dependency;
public MyObject() {
// initialize the dependency
}
public boolean getValue() {
return this.dependency.getValue();
}
public void setValue(boolean value) {
this.dependency.setValue(value);
}
}
This doesn't use inheritance or interfaces for anything, but it does create an abstraction. Consuming code doesn't know anything about the ThirdPartyObject or the details of its implementation. Following the Law Of Demeter the details of that implementation have been abstracted behind a custom object which you control. This can be very useful for de-coupling your code from implementation details you don't control.
Abstraction is a process where you show only “relevant” data and “hide” unnecessary details of an object from the user.
For example, when you login to your Amazon account online, you enter
your user_id and password and press login, what happens when you press
login, how the input data sent to amazon server, how it gets verified
is all abstracted away from the you.
Another example of abstraction: A car in itself is a well-defined
object, which is composed of several other smaller objects like a
gearing system, steering mechanism, engine, which are again have their
own subsystems. But for humans car is a one single object, which can be managed by the help of its subsystems, even if their inner details
are unknown.
Also to be noted that abstraction hides the implementation details but implementation can be shown even i.e. member functions with definitions can also be present, unlike Interface which provides total Abstraction.
Source: BeginnersBook.com
My summary is "hiding the details"; in the case of programming, abstraction is more like your first definition.
For supporting code, you don't really need to look too far. Abstraction is all around. Consider the common data structure string.
A string within a computer is actually bytes converted to a specific character set strung together. (no pun intended)
Therefore, when you put "hello, world" to you, it's a phrase in quotes. When the computer run it, it creates a data structure string which itself contains the bytes and various state to represent the given string. You don't (usually) care how the string object is working. It does and you move on with your goal. That is as basic of an example of abstraction as I can get.
Abstraction is the process by which data and programs are defined with a representation similar in form to its meaning, while hiding away the implementation details.Abstraction involves the facility to define objects that represent abstract “actors” that can perform work, report on and change their state, and “communicate” with other objects in the system.
Abstraction can be seen in two ways:
Data Abstraction - Data abstraction is the way to create complex data types and exposing only meaningful operations to interact with data type, where as hiding all the implementation details from outside works.
Control Abstraction - Abstraction of behavior. Provides an easier, higher level API to hide client from unnecessary execution details.
Abstraction is a way to promise that a class implementing a given abstraction will have a given behaviour. Thus, abstract classes cannot be directly instantiated, they first need to implement the abstraction.
Abstract classes are thus meant to be implemented by a concrete class that declares and defines a method matching the abstract contract. An abstraction can however provide some concrete behaviours along with abstract ones.
Abstraction is done in Java through abstract classes and through interface. In C++, abstraction is achieved through the usage of virtual methods inside a class. Note that Java interfaces were only created as (unlike C++) multiple inheritance is not allowed in this language.
In simple terms
Abstraction: Showing what is necessary and hiding unnecessary details. Ex if your class has 10 functions but only 2 should be useful by the consumer of the class that you make those functions as public and other are private, so what is visible to the consumer is what is needed, instead of showing it all.
Encapsulation: Hiding the complexity to the consumer of the class. Ex. if your class needs two variables to store min and max, you encapsulate them under getter and setter and implement all the validations and checks in the getter and setter. this way you hide the complexities.
Well I will explain abstraction with a real world example. Say in your house you do have an electric plug and many devices can connect to the same plug but plug will never have an idea which device it is connected to, in other words the details of the devices is abstracted (hidden) to the plug.
Think what if we connect a device directly to electric wire without a plug? Say connect a bulb directly to a wire, then wire knows which device it is connected to and when ever we need to replace the bulb then we have to remove the wire connection from the bulb, which means bulb is tightly coupled with the wire. In other words bulb and wire knows the details where it is connected to, means not abstracted.
In object oriented world abstraction works exactly same. The class which consume other classes function/property doesn't need to know which classes function/property it is consuming and everything should be abstracted with an interface / abstract class.
Let me code the same example. Here I have a class "ElectricPlug", which is running a device. But the class "ElectricPlug" doesn't have any idea which device it is running. It can be any class implementing the interface "IDevice", which means the implementation of "RunDevice" is abstracted from "ElectricPlug". Here is the full sample code,
class Program
{
static void Main(string[] args)
{
ElectricPlug electricPlug = new ElectricPlug(new Bulb());
}
}
public class ElectricPlug
{
private readonly IDevice _device;
public ElectricPlug(IDevice device)
{
_device = device;
}
public void Run()
{
_device.Rundevice();
}
}
public interface IDevice
{
void Rundevice();
}
public class Bulb : IDevice
{
public void Rundevice()
{
Console.WriteLine("Switched on bulb");
}
}
public class ElectricPlug
{
private readonly IDevice _device;
public ElectricPlug(IDevice device)
{
_device = device;
}
public void Run()
{
_device.Rundevice();
}
}
There are two parts of object in oops
state ( properties )
behavior ( methods )
so to hiding the implementation of behavior of any object is known as abstraction
let's take a example -->
there is a cook at my home which makes delicious food . some body comes at my home and take dinner . after dinner they asked me that who made this food . i answered
i have a cook whose name is tttt , his address is tttt and his number is 0000 ( these all are the properties of cook object )
they again asked how he made this then i answered
i don't know how he made . i only know that he can make food
so abstraction means we are telling that what task our object can do instead of how my object can do a task .
So I think I have a pretty basic question. Say there's an open source Java program called com.cow.moo that you include in your project com.bee.buzz.
moo has a bunch of great classes, most of which you don't want to touch, but there are a couple you do. Now at this point, the best thing to do would be to extend the classes you want to modify, right? (I know there's been a lot said of extends vs. implements, but none of these classes are interfaces, so that's kind of out of the question.)
My question is, say this is the class in moo:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly? I don't want to heavily modify the function, just add a little bit to it. What's the best way to do this?
Tips in general in building off a larger project would be useful, too. I figure it won't even take five seconds for some of the Java experts here to come up with an answer. Thanks for your time.
The general recommendation is to favor composition over inheritance.
Say, you have an interface and an existing implementation that mostly fits you needs, like
public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }
and need another custom implementation, you could code it like that:
public class MyMilk implements MilkProvider {
private MilkProvider milk;
public MyMilk(int someValue) {
milk = new Milk(someValue); // unfortunatly we can't get rid of a depencency
// to the concrete class because we need to create
// something. An existing factory could help, but
// but usually there's none implemented.
}
public float getMilk() {
float result = milk.getMilk();
// do somethink with the result
return float;
}
}
Now, say I want to just use getMilk in my new class that extends Milk. However, getMilk in Milk relies on private variables (like currentMilk) and other functions I won't be including (like convertToGallons.) Will I have to include those other variables and functions if I want my new function to work correctly?
You won't have to include the public functions and variables. The core concept of inheritance is that, as a subclass, you get all of your parent class's public (and protected) members included in your subclass for free. So your subclass (let's say HoneyMilk) can call convertToGallons right from the get-go.
Overriding getMilk in this case is a lot trickier, since it relies on a private variable (which your subclass cannot access). My advice is to shift your mindset from treating the class as a "white box" to a "black box". What I mean by that is that you should implement your overridden version of getMilk as if you weren't actually able to see Milk's source code. While it may seem like a roundabout solution (I mean, why can't I just go tweak this line here?!), this will force you to implement your subclass using only what the parent class exposes publicly. It also heavily emphasizes the importance of abstraction, which is absolutely crucial to utilize when developing large-scale projects.
I think in this case better solution will be polymorphism (static polymorphism), or you can use reflection (do not use this way) to reach to the private variable.
You can extend the class and access instance variables throught method accessors (getters & setters) if they are public.
You can use AOP (Aspect Oriented Programming) to change your moo classes at runtime without changing its sources.
Consider too read some Composition vs. Inheritance topics.
Hope this will help you.
You won't be able to use private class members unless you use Java reflection which will be kind of ugly. If I were you (and the changes are not too heavy, in which case I'd fork the original project), I'd look at modifying the code at runtime or statically using aspect weaving (aspect oriented programming). AspectJ may look as if it had a sharp learning curve, but it's a great tool to have in your toolbox and perfectly matches your needs here.