I just came across this while reading some code and I have absolutely no idea what it means. I tried googling and whatnot but I got nothing, probably due to a lack of vocabulary. The code:
public final class GeneralPath extends Path2D.Float
{
// code and whathaveyou
}
What I know so far:
So I dont have any questions regarding the "public final class ClassName extends" portion, but I don't understand the presence of the dot/scope-resolution operator in the superclass designation. For starters, I imagine that someone is going to say something like "Java doesn't have a scope-resolution operator" to clarify some difference in nuances between Java and Cpp/other-OOP-languages, which is fine, as I appreciate knowing subtle distinctions like that. The "private" keyword killed me in a hw assignment once and I wish someone had noted the difference between "private" in Java and C then.
Im confused because clearly it is not referencing a member of the superclass, as the "member" is capitalized, and even if it were, it would seem redundant to reference a member of an object rather than just the object class itself. Furthermore, I failed to find information on the subject since most people who write java how-to's tend to start with the simpler concepts like "basic" class inheritance, and so I couldn't find anything involving the "dot" operator in relation to using the "extends" keyword.
In case I am using too many technical terms, I want to know why they used the dot operator for "Path2D.Float", or at least, what the dot operator does in this context.
Thanks a million!
The GeneralPath class is extending a class Float that is nested inside the Path2D class, which is defined something like this:
public class Path2D {
public static class Float {
// ...
}
// ...
}
Related
I am studying the fragile base class problem and found the following paper interesting: https://www.research.ibm.com/haifa/info/ple/papers/class.pdf
In this paper it is argued that it would be great if Java had a 'sealed' access modifier; not like 'sealed' in C#, which is equivalent to Java's 'final' keyword. The sealing mechanism proposed would make it impossible to extend these sealed classes outside of their packages.
However, most of the material that I have found about the FBC problem dates back to the late 90s, early 00s, so it makes me wonder if the 'problem' is no longer a major issue.
I know that Joshua Bloch is an advocate of restrictive use of inheritance, especially across libraries, and he certainly seems to be a Java authority.
I know how to make oligomorphy happen by creating a set of final inner classes that inherit from a class with a private constructor, but this seems a bit inappropriate somehow.
Is the sealing proposed basically similar to making classes default/package-private, or is there actually some kind of class sealing mechanism in Java today?
However, most of the material that I have found about the FBC problem dates back to the late 90s, early 00s, so it makes me wonder if the 'problem' is no longer a major issue.
I think it's more that the issue is now well-understood. Similarly, you won't find too many recent papers discussing problems with GOTO and how to address them, not because these problems no longer exist, but because people now know how to avoid them.
Is [the proposed class sealing mechanism] not basically the same thing as making classes default/package-private?
No. Package-private classes and "sealed" classes are similar in that both cannot be extended by classes outside the package, but they differ in that the former also cannot be used by classes outside the package. That is — if a class X is package-private, then a class outside its package can't even refer to X: no extends X, no X x = new X(), no Class<X> clazz = X.class. But if it's merely sealed, then a class in a different package cannot write extends X, but can still write X x = new X() and Class<X> clazz = X.class and so on. (Just as important, it can still write X x = new Y(), if Y is a subclass. So it can still take advantage of X's type hierarchy, even though it itself can't extend X.)
I know how to make oligomorphy happen by creating a set of final inner classes that inherit from a class with a private constructor, but this seems a bit inappropriate somehow.
I wouldn't say this technique is inappropriate - the real problem is that mainstream OOP languages lack a mechanism to define a type by cases. Doing this conflates cases with types (unless you hide the subclasses by making them private) but it's the only option you have in Java.
ruakh's answer addresses your question about the sealing mechanism so I'll skip that. As for avoiding the Fragile Base Class Problem, this paper presents a solution that currently works in Java. The idea is to make all public methods final and implement them in terms of protected methods. This ensures that subclasses can only override those methods you deem safe.
The problem with inheritance as implemented in mainstream OOP languages is that it's something you have to opt out of when it should be something you have to opt into. That said, other than defining a type by cases I'm not sure what other use inheritance has that's not better replaced with aggregation/composition.
There is actually no such thing as the Fragile Base Class Problem despite the fact that there's a Wikipedia page for it and even a StackOverflow question about it. The reason you cannot find any recent references to it is because it was renamed in the mid 80s to The Incompetent Programmer Problem.
The reason it was renamed was because someone finally realised the problem it describes, where changing some seemingly insignificant method in a base class has far-reaching consequences in all the inherited sub classes, is actually not a problem with oop, it is a problem of putting the wrong code in your base class.
If you want to code oop properly and you wish to make use of inheritance it surely must be completely and utterly obvious that you make sure your base classes only ever contains totally stable and totally reliable code. Because once you start deriving from it you're stuck. If you find you are tempted to change your base class once you have derived from it a few times you have essentially already shot yourself in the foot.
Faffing around with strange private hierarchies is not the answer.
I have an incredibly basic question, but searching for it in the docs has done me no good, probably because I don't know what i'm searching for. I've actually completed several programs but never used this notation i'm finding in quite a few code examples I've been researching.
Up until now, when I've instantiated a class I've basically done the following:
public ClassType mclassname;
mclassname = new ClassType();
But I've seen this used:
public ClassType _mclassname;
__mclassname = new VortexView();
I can't find the documentation for the difference in the 2, but I'm thinking that it has something to do with making multiple instances of the object impossible?
If you know what I should look for to figure this out myself, that would be sufficient.
I just can't find it in the documents for instantiating classes.
Nested classes can be declared private whcih means they can only be used as a type inside the enclosing class.
Prefixing the names of class members with underscores has no syntactic meaning. It is a convention from C++ (and Python where it's specifically used to mark private members) that is not generally used in Java, but not uncommon among programmers who are more familiar with C++ or Python.
First this IS a Java question so forgive this first C#-related explanation...
I've most recently been using C# where one .cs source file can contain multiple class definitions, example...
// Servers.cs
public class Server {
}
public class ServerList : ArrayList <Server> {
}
I do the above because it reduces the number of source files and keeps the two classes together.
In Java of course it's one class to one .java file but I had the idea of nesting the Server class as follows...
//Servers.java
public class ServerList extends ArrayList<ServerList.Server> {
// Edited to make Server class 'static'
public static class Server implements Serializable {
}
}
This builds without compile time errors or warnings but I can't decide if it's right.
The more I look at it, the more I'm happier with it but I'm still worried that it may be considered bad practice or I could run into problems along the line.
So the question...is this OK to do? Sorry if this is a rookie Java question (or even a rookie OOP question - despite using OOP going back to mid 1990s with C++, I'm self taught and have never tried something like this).
EDIT:
Many thanks to all who have provided comments/pointers to this question.
Firstly I've edited my code to make the Server class static - I expect I would have discovered this down the line but it's good to know from the start that I should be approaching it this way.
To expand on things related to other comments...
I have reasons for extending ArrayList rather than using ArrayList (or List) in associated code. I didn't include the code (haven't started yet) but ServerList will encapsulate specific handling of Server objects (including searching on Server-specific fields/members).
Also I'm using ArrayList rather than List as I'll be using an instance of ServerList to bind to an Android Spinner widget (nice and easy with an ArrayAdapter). Sorry I didn't mention Android but my question was (in my mind) specific to Java practice and not really to my choice of classes to achieve what I'm looking to do.
As for extensibility / inheritance etc with respect to other programmers (or myself) using the Server or ServerList classes at a later date, they really are quite specific to the requirements of my current project...not necessarily a good OO approach to class definition I admit (and not usually my approach) but they serve my project best in terms of usability and efficiency.
Thanks again to all.
If you want to mirror your first example more closely, you should make your inner class static:
public class ServerList extends ArrayList<ServerList.Server> {
public class static Server implements Serializable {
}
}
That means that the inner class can be created independently and is not related to the outer class. Otherwise, each inner class would be linked to its outer class (and would have access to those class' members as well) and would therefore be required to be created from within the context of ServerList.
I have two issues with this:
since Server is the important class here, it should be a top level class. Having it as an inner class IMHO makes your code unintuitive, harder to understand. (And as #EboMike pointed out, whichever way you do it, the inner class should be static.)
I don't see a good reason to subclass ArrayList<Server> - apart from creating an extra class of minimal use, this ties its implementation to ArrayList, which limits your future options. I would prefer declaring List<Server> on public interfaces - program to interfaces, not to implementations. It is just as readable as ServerList, and more usable, since any Java programmer will know what it is, and how to use it.
I can be perfectly fine to nest classes. Try searching google for nested classes:
http://www.javaworld.com/javaworld/javatips/jw-javatip75.html
That is a good article on it. But to answer the question, no it is not "bad practice" but there are specific times you will use it.
It is technical perfect legal do do this, if you have a good reason.
For example the Java Map Interface do something (not 100%) similar: It has an Inner Interface Map.Entity, and defined an entry set, that uses this Inner Interface (Set<Map.Entry<K, V>> entrySet()) .
Anyway, you should make the inner class static, if you do not need access to the outer class within the inner one.
So most of us know how to access an outer class from an inner class. Searches with those words give oodles of answered questions on that topic. But what I want to know is why the syntax is the way it is.
Example:
public class A
{
private class B
{
public void c()
{A.this.d();}
public void d()
{System.out.println("You called the d() in the B class! Oh noes!");}
}
public void d()
{System.out.println("You've called d()! Go, you!");}
}
Why is it A.this.d()? It looks like this is a static field of class A, but... * am confused *
Forgive me if this is a repeat; like I said, searches with those words give how-answers.
A non-static inner class is always associated with a specific instance of the outer class. The A.this syntax is just a way to refer to this instance. I cannot think of any other simpler or clearer way of doing this. My first reaction when I saw this syntax was "ouch, ugly", but when I though a little about it I realized that it was pretty neat.
(Yes, it does look like accessing a static field, but then again, you cannot have a static field this, so it isn't ambiguous.)
I think it's just a simple way of clarifying which this one means (since this, without the qualifier, refers to the inner this which is a reference to an object of type B).
Since this is a reserved keyword it can't be confused with some static filed/method of class A.
I supposed they could have introduced some other keyword like enclosing and let you go through enclosing.this (similar to the super keyword). I just don't think they saw it as necessary to introduce a new keyword in this situation.
Would you prefer some other syntax?
Why is it done that way? Really, it's just because of the way it is. It works, it sort of makes sense, and there's no need to come up with fancy syntax to do the job.
When you see something like this:
x.y.z
The . can mean a lot of things:
Subpackage separator
Member field access
Nested type separator
In other words, the . is overloaded to serve many grammatical functions within Java programming language. It may lead to confusion, and it can be problematic, but that's just the way it is.
It helps to follow naming convention, but certain things can still look ambiguous and/or confusing.
See also
Sun Naming Conventions
JLS 6.5 Determining the Meaning of a Name
This section has many examples showing how names can be resolved
I work on a team of Java programmers. One of my co-workers suggests from time-to-time that I do something like "just add a type field" (usu. "String type"). Or code will be committed laden with "if (foo instanceof Foo){...} else if( foo instanceof Bar){...}".
Josh Bloch's admonition that "tagged classes are a wan imitation of a proper class hierarchy" notwithstanding, what is my one-line response to this sort of thing? And then how do I elaborate the concept more seriously?
It's clear to me that - the context being Java - the type of Object under consideration is right in front of our collective faces - IOW: The word right after the "class", "enum" or "interface", etc.
But aside from the difficult-to-demonstrate or quantify (on the spot) "it makes your code more complicated", how do I say that "duck-typing in a (more or less) strongly-typed language is a stupid idea that suggests a much deeper design pathology?
Actually, you said it reasonably well right there.
The truth is that the "instance of" comb is almost always a bad idea (the exception happening for example when you're marshaling or serializing, when for a short interval you may not have all the type information at hand.) As josh says, that's a sign of a bad class hierarchy otherwise.
The way that you know it's a bad idea is that it makes the code brittle: if you use that, and the type hierarchy changes, then it probably breaks that instance-of comb everywhere it occurs. What's more, you then lose the benefit of strong typing; the compiler can't help you by catching errors ahead of time. (This is somewhat analogous to the problems caused by typecasts in C.)
Update
Let me extend this a bit, since from a comment it appears I wasn't quite clear. The reason you use a typecast in C, or instanceof, it that you want to say "as if": use this foo as if it were a bar. Now, in C, there is no run time type information around at all, so you're just working without a net: if you typecast something, the generated code is going to treat that address as if it contained a particular type no matter what, and you should only hope that it will cause a run-time error instead of silently corrupting something.
Duck typing just raises that to a norm; in a dynamic, weakly typed language like Ruby or Python or Smalltalk, everything is an untyped reference; you shoot messages at it at runtime and see what happens. If it understands a particular message, it "walks like a duck" -- it handles it.
This can be very handy and useful, because it allows marvelous hacks like assigning a generator expression to a variable in Python, or a block to a variable in Smalltalk. But it does mean you're vulnerable to errors at runtime that a strongly typed language can catch at compile time.
In a strongly-typed language like Java, you can't really, strictly, have duck typing at all: you must tell the compiler what type you're going to treat something as. You can get something like duck typing by using type casts, so that you can do something like
Object x; // A reference to an Object, analogous to a void * in C
// Some code that assigns something to x
((FoodDispenser)x).dropPellet(); // [1]
// Some more code
((MissleController)x).launchAt("Moon"); // [2]
Now at run time, you're fine as long as x is a kind of FoodDispenser at [1] or MissleController at [2]; otherwise boom. Or unexpectedly, no boom.
In your description, you protect yourself by using a comb of else if and instanceof
Object x ;
// code code code
if(x instanceof FoodDispenser)
((FoodDispenser)x).dropPellet();
else if (x instanceof MissleController )
((MissleController)x).launchAt("Moon");
else if ( /* something else...*/ ) // ...
else // error
Now, you're protected against the run-time error, but you've got the responsibility of doing something sensible later, at the else.
But now imagine you make a change to the code, so that 'x' can take the types 'FloorWax' and 'DessertTopping'. You now must go through all the code and find all the instances of that comb and modify them. Now the code is "brittle" -- changes in the requirements mean lots of code changes. In OO, you're striving to make the code less brittle.
The OO solution is to use polymorphism instead, which you can think of as a kind of limited duck typing: you're defining all the operations that something can be trusted to perform. You do this by defining a superior class, probably abstract, that has all the methods of the inferior classes. In Java, a class like that is best expressed an "interface", but it has all the type properties of a class. In fact, you can see an interface as being a promise that a particular class can be trusted to act "as if" it were another class.
public interface VeebleFeetzer { /* ... */ };
public class FoodDispenser implements VeebleFeetzer { /* ... */ }
public class MissleController implements VeebleFeetzer { /* ... */ }
public class FloorWax implements VeebleFeetzer { /* ... */ }
public class DessertTopping implements VeebleFeetzer { /* ... */ }
All you have to do now is use a reference to a VeebleFeetzer, and the compiler figures it out for you. If you happen to add another class that's a subtype of VeebleFeetzer, the compiler will select the method and check the arguments in the bargain
VeebleFeetzer x; // A reference to anything
// that implements VeebleFeetzer
// Some code that assigns something to x
x.dropPellet();
// Some more code
x.launchAt("Moon");
This isn't so much duck typing as it is just proper object-oriented style; indeed, being able to subclass class A and call the same method on class B and have it do something else is the entire point of inheritance in languages.
If you're constantly checking the type of an object, then you're either being too clever (though I suppose it's this cleverness that duck typing aficionados enjoy, except in a less brittle form) or you're not embracing the basics of object-oriented programming.
hmmm...
correct me if I am wrong but tagged classes and duck-typing are two different concepts though not necessarely mutally exclusive.
When one has the urge of using tags in a class to define the type then one should, IMHO, revise their class hiearchy as it is a clear sing of conceptual bleed where an abstract class needs to know the the implementation details that the class parenthood tries to hide. Are you using the correct pattern ? In other words are you trying to coerce behaviour in a pattern that does not naturally support it ?
Where as duck-typing is the ability to loosely define a type where a method can accept any types just so long as the necessary methods in the parameter instance are defined. The method will then use the parameter and call the necessary methods without too much bother on the parenthood of the instance.
So here... the smelly hint is, as Charlie pointed out, the use of instanceof. Much like static or other smelly keywords, whenever they appear one must ask "Am I doing the right thing here ?", not that they are inhertitly wrong but they are oftenly used to hack through a bad or ill fitted OO desing.
My one line response would be that you lose one of the main benefits of OOP: polymorphism. This reduces the time to develop new code (developers love to develop new code, so that should help your argument :-)
If, when adding a new type to an existing system, you have to add logic, aside from figuring out which instance to construct, then, in Java, you are doing something wrong (assuming that the new class should simply be a drop in replacement for another).
Generally, the appropriate way to handle this in Java is to keep the code polymorphic and make use of interfaces. So anytime they find themselves wanting to add another variable or do an instanceof they should probably be implementing an interface instead.
If you can convince them to change the code it is pretty easy to retrofit interfaces into the existing code base. For that matter, I'd take the time to take a piece of code with instanceof and refactor it to be polymorphic. It is much easier for people to see the point if they can see the before and after versions and compare them.
You might want to point your co-worker to the Liskov substitution principle, one of the five pillars in SOLID.
Links:
Wikipedia entry
Article written by Uncle Bob
When you say "duck typing in strongly-typed languages" you actually mean "imitating (subtype) polymorphism in statically-typed languages".
It's not that bad when you have data objects (DTOs) that don't contain any behaviour. When you do have a full-blown OO model (ask yourself if this is really the case) then you should use the polymorphism offered by the language where appropriate.
Although I'm generally a fan of duck-typed languages like python, I can see your problem with it in java.
If you are writing all the classes that will ever be used with this code, then you don't need to duck-type, because you don't need to allow for cases where code can't directly inherit from (or implement) an interface or other unifying abstraction.
A downside of duck-typing is that you have an extra class of unit tests to run on your code: a new class could return a different type than expected, and subsequently cause the rest of the code to fail. So although duck-typing allows backward-flexibility, it requires a lot of forward thinking for tests.
In short you have a catch-all (hard) instead of a catch-few (easy). I think that's the pathology.
Why "imitate a class hierarchy" instead of designing and using it? One of the refactoring methods is replacing "switch"es (chained ifs are almost the same) with polymorphism. Why use switches where polymorphism would lead to cleaner code?
This isn't duck typing, it is just a bad way to simulate polymorphism in a language that has (more or less) real polymorphism.
Two arguments to answer the titled question:
1) Java is supposed to be "write once, run anywhere," so code that was written for one hierarchy shouldn't throw RuntimeExceptions when we change the environment somewhere. (Of course, there are exceptions -- pun -- to this rule.)
2) The Java JIT performs very aggressive optimizations that rely on knowing that a given symbol must be of one type and one type only. The only way to work around this is to cast.
As others have mentioned, your "instance of" doesn't match with the question I've answered here. Anything with any types, duck or static, may have the issue you described. There are better OOP ways to deal with it.
Instead of instanceof you can use the Method- and the Strategy-Pattern, mixed together the code looks much better than before...