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.
Related
I've found a proper way to implement the logic I was looking for, but I'm curious as to why the following doesn't work. Half an hour searching yielded no answers but it is possible I'm not wording the question properly.
What I wanted to do was limit the type parameter such that Collections would not be accepted. While I can test the parameter type, I'd rather have the IDE indicate that the Class doesn't accept a Collection as a type parameter. I'm aware that the keyword excludes doesn't exist but I hope it helps illustrate the question at hand.
public class Foo<K excludes Collection, V>
{
//TODO: Carry out Collectionist operations
}
Is there any way to do this in Java? I presume this isn't a best practice, even if it is possible, but I'd like to satiate my curiosity in an effort to expand my understanding of Generics.
Thank you for your time and consideration!
Excluding certain types is not possible. Due to the way how Java types interfaces, I could simply roll up my own Collection that has the exact same operations, and it would not be excluded.
Just for the sake of curiosity it is a fair question, I am not aware of a way of achieving it at compile time though. You can place a runtime check in Foo's constructor.
It is not possible to implement like that.
The current version of generics only supports extends or super. It does not support any negative scenario like that.
I have noticed in SONAR that I have a violation that is called IllegalType in my java Code. I looked for this and in Checkstyle explain about it this :
Checks that particular class are never used as types in variable declarations, return values or parameters. Includes a pattern check that by default disallows abstract classes.
Rationale: Helps reduce coupling on concrete classes. In addition abstract classes should be thought of a convenience base class implementations of interfaces and as such are not types themselves.
But I don't understand really why is this a problem in my code. If anyone can explain me better maybe with an example it could be great!. Thanks at all.
What Aaron Digulla said in his comments is a good practice for sure. However I also found this IllegalType issue with my own Abstract Classes (instead of interfaces) which don't seem to me to be pretty clear. I understand the benefits of using intefaces insteaf of classes, and I also understand that abstract classes are partially classes (so much more a class than a interface) but I don't see the benefits of this rule, as I can find cases where I can return a concrete class (no abstract) which is a superclass of what I'm actually returning.
Not all violations that Sonar finds are for everyone. The check IllegalType (docs) tries to make sure you don't use classes that most developers deem "broken" in some way like Vector (use ArrayList instead).
Other classes shouldn't be used as a return type. Always return List instead of ArrayList, Set instead of HashSet, Map instead of HashMap - that way, consumers of your code don't know any unnecessary details about your implementation. If you find you need to replace HashMap with TreeMap (or vice versa) in a method, that will be much more simple if you don't have to change all the places as well where this method was called.
Generally, the check isn't a problem as such (your code works) but fixing those will make your code easier to maintain in the future.
Whenever we talk about objects we have instances, methods : functions : behavior, member variable: state, like so many interchangeable words. but for "Class" till now i didnt see people who have used some other word. So is there any other word in java which can be used(or in use)(dont tell any English synonym) which i can use. while explaining my code.
EDIT: Dont invent looking at this question it should be in use which i might not know
The concept of class is related to 'universal' and all that logic (abstraction/universal against instantiation/particular) comes from Aristotle (derived from Plato) philosophy. The OOP seems to take concepts from that filosophy.
The question for me is very relevant. Here is a link from wikipedia (http://en.wikipedia.org/wiki/Aristotle#Universals_and_particulars), and if you read this resume you could understand the relations between Aristotle philosophy and OOP.
Aristotle disagreed with Plato on this point, arguing that all universals are instantiated. Aristotle argued that there are no universals that are unattached to existing things. According to Aristotle, if a universal exists, either as a particular or a relation, then there must have been, must be currently, or must be in the future, something on which the universal can be predicated. Consequently, according to Aristotle, if it is not the case that some universal can be predicated to an object that exists at some period of time, then it does not exist.
Cool ah?
I hope it helps...
Instances, methods, functions, behaviour, etc., are all English words, so I don't quite comprehend your restriction.
So, for Class: Type.
Actually, those all have slightly different meanings: A method is a function attached to a class (they are often incorrectly used interchangably), while behaviour refers at a higher level to what a function/method does.
State refers to the specific value of a variable, or of many variables combined.
To answer your question, another word for class would be object, as you said yourself.
[Edit] It appears I spoke too tongue-in-cheek. As many people have pointed out, 'object' can also refer to an instance of a class. I think your safest bet would be to use class when you mean a class, instance when you mean an instance, spade a spade etc.
Well I heard people referring to it as a blueprint (meaning that it is a definition of what kind of state and what operations an instance will provide).
I'm pretty sure that class is the best way to describe a class in Java.
It is a pretty specific idea, and any synonym will not be able to capture the full meaning of the word.
I saw many times the word Clazz used in the code to avoid the reserved word. Does that help?
Prototype?
I would suggest "Mould" to describe the role of a class
Refer to SoloLearn on google playstore.
Class is also known as Object Factory.
But FYKI, only "class" keyword is used to create a class.
Good luck
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...
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.