Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Liskov Substitution Principle (LSP) states that if an object o1 is a type of S and it can be substituted for object o2 that is a type of T without violating the original behavior(s) of all its users, then S is a subtype of T.
The common example used to show LSP violation is Rectangle and its derivative type, Square. The argument is that although intuitively the Square seems to be subtype of Rectangle, but there is some behavior of Square which is different from Rectangle. The conclusion is that the Square cannot be a subtype of Rectangle by LSP.
All explanations I discovered end there and I find it not helpful. I want to know what should I do if I have that problem? Create S which is not a subtype of T, and then what? What solutions do I have to solve it?
Can someone please enlighten me with an answer for the overhanging question?
edit: Rather than elaborating the example here, I refer you to this article.
You can use 'HAS A' or 'USES' relationship if you can not establish 'IS A' relationship.
This means that instead of having class B inherit from class A, you can have class B contain an instance of class A. This is also good coding practice to avoid tight coupling between class A and class B.
This question is reviewed in the book Effective C++ 3rd Edition by Scott Meyers, Addison Wesley May 2005. In chapter 6, Item 32.
There Meyers makes sample class for Rectangle and class for Square which inherits the first one and talks extensively about the arising problems using assertions.
The conclusion of the Item is:
"Public inheritance means “is-a.” Everything that applies to base
classes must also apply to derived classes, because every derived
class object is a base class object."
Currently the book can be found or bought on the internet.
The LSP is a more precise definition of the "is-a" relation, if you class violates the LSP is not a suitable candidate to be derived from the base class. It is a signal that something is wrong in your design.
Two point worth to be noticed: violating LSP is going to break the base class and not the derived class, this is very dangerous in legacy code with very little tests coverage, something that has a clear "is-a" relationship in the mathematical world (like square and rectangle) they may don't share that relationship in the domain of your application.
You can extract the common properties into an interface or an abstract type and use this as base. Differences can still be implemented in the derived type.
This way you keep your IS-relation.
The lesson to be learned from LSP and the rectange/square example is that IS_A has nothing to do with maths or biology or anything that seems obviously IS_A by intuition.
IS_A is solely a relationship of behavior. Square is not a rectangle in OOP, because it doesn't have the same behavior. But rectangle has the same behavior as square plus some extra which does not violate any behavior of square. So in OOP rectangle IS_A square and it makes perfect sense to implement it like that even if it defies maths and intuition.
Related
This question already has answers here:
Prefer composition over inheritance?
(35 answers)
Closed 2 years ago.
I was going through the difference between inheritance and composition. Everyone has praised composition over inheritance, so questions is how do we make choice ? Also if we didn't use inheritance at all then what are we going to miss as per OOP principal ?
It really comes down to how your data is structured. Inheritance is used for "is a" relationships while composition is used for "has a" relationships.
For example, if you were look at cars.
Inheritance: you would have 'Toyota', 'Honda', 'BMW' under 'Car' because they are types of cars.
Composition: you would have 'Engine', 'Wheels', 'Door' under 'Car' because they are parts that make up the car.
'Toyota', 'Honda', 'BMW' aren't parts of a car same way 'Engine', 'Wheels', 'Door' aren't types of cars.
This is a big complicated topic, perhaps too much to be described in a few SO posts.
Inheritance can be tricky, People have done Ph.D dissertations on this. Most of the time when I write new code I keep inheritance to a minimum.
When your Dog class inherits Mammal all the state/behavior of Mammal must still apply.
(the dog is a mammal). Is a platypus a mammal? Biology-yes, but it may not apply to your needs. Especially when you have mutable objects you run into
messy situations such as https://en.wikipedia.org/wiki/Circle%E2%80%93ellipse_problem#Description
Also in real life there's often goofy couplings between parent and child classes.
You cannot say that one should be preferred over another. It depends how the data is structured and what representation is required for a particular data model. There is a simple way to remember what to use:
Inheritance = is
The fact an object inherits from another means the object actually is what it inherits from, hierarchically. Let's take an example from the simplified taxonomy in biology. Working with the kingdom Animalia, we can say that Opossum is a Mammal, which is Chordate, which is animal. Therefor here we have a chain of the inheritance: Opossum extends Mammal, Mammal extends Chordate, Chordate extends Animal. Each of the group has various characteristics that all the subtypes inherit.
Composition = has
The composition is has. However, here this relation should be rather understood as is composed from or contains. If we stay in the world of biology, we can say an Opossum has a head, tail, body and 4 legs, therefore there is a composition relationship between these objects. This is in Java represented as instance fields:
class Opossum {
Head head;
Body body;
Leg[] legs = new Legs[4];
}
You can google thousands articles about it. So if you want to understand more deeply, google and learn, we dont have to reinvent wheel here.
If you want short explanation what composition over inheritance means, it basically says - do not overengineer your solution with some super complex inheritance. If you develop something and you see some clear advantages of inheritance and you cant achieve the same with composition, you are free to use inheritance. If you dont see it or you can achieve the same with composition, use composition.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Some utility classes (think java.lang.Math) declares only a private constructor in order to prevent instantiation of the class.
Is there any particular reason for why such classes are not implemented in terms of a 0-instance enum? It seems to me like enums is a more direct way of controlling instantiation than access modifiers on constructors. It also prevents the class itself from creating instances which both prevent the programmer from shooting himself in the foot and convey a guarantee outwards of no instances.
Joshua Bloch advocates the use of enums for singletons. Shouldn't the same benefits apply to 0-instance utility classes?
My question: What are the pros/cons of 0-instance enums vs private constructors. (I personally see no drawbacks of using an enum, though private constructors seems to be the more prevalent approach.)
(I know java.lang.Math predates enum. I'm talking 1.5+ code here.)
The fact that enums cannot be instantiated is a side-effect. When you declare something as an enum, people would expect it to be an enum; it will appear as enum in the IDE, code analysis tools, whatever.
Following the principle of least astonishment, and given that the user doesn't care of how you internally achieve that, I think it's better to use a private constructor, and also throw an Error from that constructor, provided someone tries to instantiate it with reflection.
So, to summarize the answers and comments so far:
Arguments supporting 0-instance enums:
Enum solves the problem of controlling instantiation of classes which is precisely what a 0-instance utility class needs.
Weekday has 7 instances, Month have 12, MySingleton has 1 (and should according to Joshua Bloch be implemented by means of an enum) and MyUtilityClass has 0 instances. There is no conceptual difference between the last case and the former ones.
A 0-instance enum guarantees that no instance will be created, not even from within the class itself.
Arguments against 0-instance enums:
Does not follow the principle of least astonishment; when people see an enum, they expect it to follow the text-book examples of non-empty enums such as weekdays, status codes etc.
The 0-instance enum is an idiom not widely used and thus not something other programmers recognize easily. I.e. it's less readable than using private constructors.
Enums are cluttered with implicit synthetic methods, which means that those names are not allowed for custom-defined methods. Furthermore, the fact that a public API exposes methods which should not be used can range from awkward to broken.
Other notes
Related question and answer.
Blog post on the subject by Peter Lawrey.
I don't know of any technical drawbacks with either approach.
As for elegance, that is a matter of opinion, and (IMO) not particularly relevant to the real purpose(s) of most computer programs.
By contrast, readability, maintainability and correctness are properties that are relevant to purpose. And one aspect that helps to make a program readable is the use of idioms that other programmers can readily recognize. Zero-instance enum types are an interesting idea ... but private constructors are the established idiom for preventing instantiation.
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
Can someone please explain to me how to implement these these types of code and explan what the difference between the three are? I am coding in java.
I'm goign to take a shot at it because I recently tried to understand those and this is a good way to see if I did :) because If you can't explain something you haven't really understood it :)
Casting is fairly simple. It means to pretty much convert a value or object of a certain type to a different type. This way you can for example turn a float into an integer
float y = 7.0
int x = (int) y
x will now be 7.
Of course you can't simply cast any type to any other type. There are limitations which you should search for on google - i could never cover all of them.
Polymorphism sounds similar but is actually something else. As I understand it it means that certain objects can be of multiple types. For example of you have a class that extends another class any instance of the parent class can also be of the type of the derived class.
class Base {...}
class Derived extends Base {...}
Base obj1 = new Base();
Derived obj2 = new Derived();
obj1 = obj2;
Over the course of this snippet obj1 will have been an instance of Base first but then it will be an instance of Derived which is a class derived from base. This is possible because instances of derived classes contain an "inner object" (i don't know the official name) of the base class. When you cast the Base instance to an instance of Derived you will actually get this "inner object"
Hope this helps
refer to the documentation from Oracle : http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
http://docs.oracle.com/javase/tutorial/java/IandI/index.html
True polymorphism (i.e., multiple inheritance) is not available in Java. However, you can get a good approximation using "Interfaces", though your classes need to implement all of the functions provided by the interface (link to Java Interfaces).
You can also emulate multiple inheritance using delegated setters/getters on classes. This can be complicated, but it can also give you the effect of multiple inheritance.
This topic is discussed at length in this Stack Overflow post.
Ok, so this question will probably get closed, but hell, its 4:30 in the morning and I can't sleep because I'm still frustrated with my Java midterm last night. The test was an on-line thing and you get to see how you did immediately.
The test was poorly written with tons of typos and grammatical errors. I don't normally care about that, except that when you add in vaguely phrased questions you aren't sure how to interpret the question anymore, since you can't assume you can parse it according to the normal rules of English.
One particular question that sticks in my craw:
What is the base type for Collections? (It was written like that, with the capital C, which I think is important.)
The only two relevant possibilities were Object and Collections. Now I know that Collections is the class from which most of the collection classes derive, so I initially selected that. On my second run-through I thought, wait a minute. By base type, does he mean what is the base class from which Collections derives? (After all, by capitalizing the C it indicated Collections class in a specific sense, rather than just collections in a generic sense.) So I changed my answer to Object, because I know that Collections extends Object.
Turns out I was right the first time.
So my question, then: if I kvetch about this question, do I have a leg to stand on? Or am I missing some distinction between base type and base class?
Now I know that Collections is the class from which most of the collection classes derive, so I initially selected that.
Well that's a problem to start with... because it isn't. Collections is a utility class with only a private constructor, with no subclasses.
Collections does have Object as a superclass, but it isn't a superclass for anything. The highest level class (other than Object) which many collections derive from is AbstractCollection, which then has AbstractList etc as subclasses.
It sounds like it was a bad question, but your own understanding was flawed too. Sounds like a no-score draw, but you should possibly raise the test quality with someone.
Assuming that the question had a spelling error, and the c should have been lowercase: The base type for most collection classes is the Collection<E> interface.
If the question was spelt properly (capitalized 'C' intended and not a typo): The base type of the Collections class is Object.
I'd say the question is poorly phrased anyway.
I guess the question is actually asking about the main/base types of java collection framework. the Types here would be like Set, List, Queue.. but not in context SuperType, SuperClass.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
First off, I know next to nothing about language theory, and I barely know any other languages except Java, but I had an idea that I think would be cool, but I need you guys to tell me:
a: why it sucks
b: how language x has had that for years
c: how my mind sucks
d: all of the above
The idea would give composition the same ease of code reuse that extends does.
So if you had a class like this:
public interface A {
public void methodInA();
}
And then you had a class like this:
public class B {
private composed A;
public B() {
// construct A within constructor
}
}
You would then be able to do this:
B myB = new B();
myB.methodInA();
Without having to add in the delegation in B's class. But you could also do the same as with inheritance, ie:
#Overrides
public void methodInA(){
// B's own delegation method
}
Disadvantages include:
methods are hidden in the source code, making it less obvious where the call is coming from, but this is also the case with extends
if composed fields share the same method signature there needs to be a conflict resolved (how do conflicting interfaces solve this?)
if you wanted to have several composed fields of the same type, there would be an obvious conflict for which field to delegate to
probably 100 other things I've not thought of
Like I say, I'm obviously no language theorist, and I haven't spent ages thinking about it, the idea just popped in my head and I wanted to know how wrong I am. I just think it would be kind of cool.
It sounds cool but I think it makes for some horrible language constructs. Obviously there is a problem if you declare more than one 'composition' of the same class, but even if you forbid that what about the case where a call matches a method in more than one of the (different) composed classes? You would have to specify which one was called in the main class, and you would need extra syntax for that. The situation becomes even worse if there are public members in the classes.
Composition is used to prevent problems with multiple inheritance. Allowing composition like this is effectively permitting multiple inheritance, at least in terms of resolving which method to call. Since a key design decision with Java was to disallow multiple inheritance (for good reasons) I think it unlikely that this would ever be introduced to Java.
I think if you restricted it such that a class could only use this feature to compose a single class it would be somewhat useful and would avoid a lot of the headaches that are being discussed.
Personally I hate inheritance of concrete classes. I'm a big proponent of Item 14 from Bloch's Effective Java, Favor composition over inheritence. I think that something like this would make it a little easier to implement the idiom he recommends in that item.
Honestly, if you really knew what you were doing I'll bet you could write a compiler annotation that would handle this. So assuming you had a class Bar that implemented the interface IBar, your class would look like this:
public class Foo {
#Delegate(IBar.class)
private Bar bar;
// initialize bar via constructor or setter
}
Then during compilation Foo could be made to implement IBar and any of the methods on that interface that weren't already implemented by Foo would end up being generated to look like this:
public Baz method1(Qux val) {
return bar.method1(val);
}
As mentioned above you would want to make the restriction that only one field per class could use this annotation. If multiple fields had this annotation you'd probably want to throw a compilation error. Alternatively you could figure out a way to encode some sort of precedence model into the parameters passed to it.
Now that I've written this out that seems kinda cool. Maybe I'll play around with it next week. I'll update this if I manage to figure anything out.
I'm not sure that I see a clear advantage to doing this though. I understand the point you are making. At the moment to call a method on A you have to myB.getAInstance().methodInA(), but you want to make that myB.methodInA().
But, what happens if you have multiple instances of A? How would the method call be resolved? Many times composition implies a one to many association so B has many A instances. What happens then?
I agree with your disadvantages listed. It may simply cause too much confusion than it is worth.
Check out what is called "Mixins" in some languages, and "Roles" in the Perl 5 Moose OO system.
There's also the difference between composition and aggregation to consider. How does the compiler know whether you mean 'is-a' or 'has-a' relationships?
Does the whole object graph become eligible for garbage collection or only the head of the graph?
A couple of the ORM mapping tools and frameworks over/around them provide for belongsTo or has-many relationships between persistent objects and some also provide for the cascading delete (for composition). I don't know of one off hand that provides the simple syntactic sugar you're looking for.
Actually, on second thought, Groovy's MetaClass and MetaProgramming idiom(s) may provide something very similar, with 'auto-magic' delegation.
Multiple inheritance is allowed in C++, I know that different but it is along the same thought process. Java was designed to not allow multiple inheritance so that there would be less confusion, therefore bugs and exploits.
What you have suggested is in direct conflict with the principles of java.
Having said that, it would be cool (not necessarily useful). I'm a java programmer who switched from C++. I like being able to make my own mistakes.