EEVblog Electronics Community Forum
Products => Computers => Programming => Topic started by: OptymizeSoham on November 07, 2022, 11:39:29 am
-
Is java.lang.Object the superclass of all the automatically inherited custom classes/objects? I was under the impression that Java did not enable multiple inheritances. I'm wondering if it's multiple inheritances if I already inherit from another class in my own class and Java forces implicit inheritance of java.lang.Object on top of it.
Is java.lang.class also the superclass of all custom classes/objects? If not, how can we retrieve the type of class for any class supplied in java reflections or call isInstance on any object?
-
Yes, java.lang.Object is the base class for any class in Java. There is still no multiple inheritance for classes - when you class B extends A, A will already extend java.lang.Object (even when you don't specify it, that happens automatically).
So an 'x instanceof java.lang.Object' will always be true (as long as x is not null). When you want to get the actual type of an object, use 'x.getClass().getName()'. Note that its bad style to base any behavior on the class of an object. Use interfaces instead.
The article you refer you is written in a very confusing way, and while I think its technically correct, it implies things which are not true. Java does not support multiple inheritance. It also does not support multiple types of inheritance (I don't even know what that means).
While implementing an interface looks similar to extending a class, its something completely different, and it also does not give you anything like multiple inheritance (because you do not inherit behavior).
-
Yes, java.lang.Object is the base class for any class in Java. There is still no multiple inheritance for classes - when you class B extends A, A will already extend java.lang.Object (even when you don't specify it, that happens automatically).
So an 'x instanceof java.lang.Object' will always be true (as long as x is not null). When you want to get the actual type of an object, use 'x.getClass().getName()'. Note that its bad style to base any behavior on the class of an object. Use interfaces instead.
The article you refer you is written in a very confusing way, and while I think its technically correct, it implies things which are not true. Java does not support multiple inheritance. It also does not support multiple types of inheritance (I don't even know what that means).
While implementing an interface looks similar to extending a class, its something completely different, and it also does not give you anything like multiple inheritance (because you do not inherit behavior).
That article is indeed poorly written, by someone that has a superficial knowledge of the topic.
In addition to the erroneous conclusion you mention, I'll add the first conclusion "Inheritance is the central point of Object-Oriented Programming". No, it isn't. Full stop.
-
In addition to the erroneous conclusion you mention, I'll add the first conclusion "Inheritance is the central point of Object-Oriented Programming". No, it isn't. Full stop.
Agreed. Inheritance is the emperor's new trousers. Beginner guides to OOP shouldn't even mention it in my humble opinion. Inheritance is the least flexible and highest coupling method to extend functionality. While it can be argued that multiple inheritance frees you from a lot of that hard coupling, multiple inheritance comes with it's own set of problems.
To explain with an example. What if you have a List of things in your program, but you want to manage them slightly differently, maybe sort the list in a special way or exclude duplicates in a special way. A dumb Java tutorial will tell you to sub-class ArrayList (or LinkedList) and crate your own MyList class. Don't do this. The argument will be "it is a list", such it meets the "is a" qualifier for a subclass. They will stop there. Continue the argument with the other side however. "has a". MyList has an ArrayList and implments the "List" interface. In fact as "ArrayList" implements "List" as well, you technical have met the "is a" at the same times as meeting the "has a", so you are not locked in or tightly coupled. Your "MyList" class can now freely change it's List implementation between ArrayList and LinkeList or any other internal storage it likes.... as long as it meets the contract of the "List" interface it will be considered the same as any other List in your application or by Java frameworks.
Don't want this to stray like a lot of these threads into bashing OOP, but Java and the original concept of OOP couldn't really be further apart. All most every single one of the basic founding principles of OOP have been degraded in Java or miss-used/abused in grotesque ways to bring them well out of proportion. Amusing to non-OOP zealots is that most of the changes to get around OOPs inflexibilities and inherent problems have been solved by techniques far more familiar in C and procedural programming. I mean, hard value encapsulation with public getters and setters is A STRUCT. Debate me. Create sole "Value classes" is a data table, in exactly the same way as a struct is in C. You then pass that value class to your decoupled static functions (so you know their don't modify state)... this is exactly how C works. You create structs of data (data table) and you pass them around between procedures. This is even transparently visible in languages like C++. That the OOP is so often circumvented to get round the issues it presents. IMHO OOP should never have stepped out beyond the GUI and directed visual interaction patterns it was intended for.
-
In addition to the erroneous conclusion you mention, I'll add the first conclusion "Inheritance is the central point of Object-Oriented Programming". No, it isn't. Full stop.
Agreed. Inheritance is the emperor's new trousers. Beginner guides to OOP shouldn't even mention it in my humble opinion. Inheritance is the least flexible and highest coupling method to extend functionality. While it can be argued that multiple inheritance frees you from a lot of that hard coupling, multiple inheritance comes with it's own set of problems.
To explain with an example. What if you have a List of things in your program, but you want to manage them slightly differently, maybe sort the list in a special way or exclude duplicates in a special way. A dumb Java tutorial will tell you to sub-class ArrayList (or LinkedList) and crate your own MyList class. Don't do this. The argument will be "it is a list", such it meets the "is a" qualifier for a subclass. They will stop there. Continue the argument with the other side however. "has a". MyList has an ArrayList and implments the "List" interface. In fact as "ArrayList" implements "List" as well, you technical have met the "is a" at the same times as meeting the "has a", so you are not locked in or tightly coupled. Your "MyList" class can now freely change it's List implementation between ArrayList and LinkeList or any other internal storage it likes.... as long as it meets the contract of the "List" interface it will be considered the same as any other List in your application or by Java frameworks.
Yes indeed.
The worst example I saw of this was where a company needed to deal with money. So they made "Money" a subclass of Integer, and the further subclassed it for more refinements. (Integer was actually appropriate in that context)
Don't want this to stray like a lot of these threads into bashing OOP, but Java and the original concept of OOP couldn't really be further apart. All most every single one of the basic founding principles of OOP have been degraded in Java or miss-used/abused in grotesque ways to bring them well out of proportion.
There I completely disagree.
There were two things that made me jump on Java in '96, before there were even IDEs available. The first was that I admired James Gosling's emacs implementation (later Unipress) from the early 80. The second was his Java whitepaper which simply and clearly explained the features in Java, why they were necessary, how they were known to work well and well together, and why some features had been deliberately omitted.
It was a superb whitepaper, and I've rarely seen its equal. There is no chance the C/C++ community could have produced such a thing because that community never made reference to other languages/environments, preferring to badly implement things that were already known to have fatal flaws.
That was all demonstrated clearly to anybody outside the C++ community by noting how fast the Java standard library implemented high quality functionality and other people were able to create their own libraries. Examples: Strings and container classes, which C++ didn't have even after a decade or so!
Amusing to non-OOP zealots is that most of the changes to get around OOPs inflexibilities and inherent problems have been solved by techniques far more familiar in C and procedural programming. I mean, hard value encapsulation with public getters and setters is A STRUCT. Debate me. Create sole "Value classes" is a data table, in exactly the same way as a struct is in C. You then pass that value class to your decoupled static functions (so you know their don't modify state)... this is exactly how C works. You create structs of data (data table) and you pass them around between procedures. This is even transparently visible in languages like C++. That the OOP is so often circumvented to get round the issues it presents. IMHO OOP should never have stepped out beyond the GUI and directed visual interaction patterns it was intended for.
You can write Fortran in any language - and many people do. Don't damn English because Harold Robbins and Danielle Steele and Barbara Cartland used it as their tool!
Having said that, Java the language is suffering the usual fate of having extra things grafted on because they are fashionable in other environments.
-
You can write Fortran in any language - and many people do. Don't damn English because Harold Robbins and Danielle Steele and Barbara Cartland used it as their tool!
Having said that, Java the language is suffering the usual fate of having extra things grafted on because they are fashionable in other environments.
I suppose we agree that it's not Java specifically at fault, but more how people have become dogmatized into using it in such a way. Not an attack of Java, but on how people implement OOP with it. Usually to the detriment of the actual functionality, IMHO. So often these engineers and I have worked with a lot of them, are more interested in satisfying some sort of fetish or religion on structure, abstraction, patterns. SOLID for example. Fine principles to have in the tool box, but writing every single tiny bit of functionality to be as generic as possible and plastering it with dogmatic patterns whether they are necessary or not.... has actually become such a grotesque caricature of OOPs intent it doesn't even resemble the "spirit" of it anymore. I honestly now ask people to count the number of lines in their code that has a tangible output and compare it against the total number of lines. I'm not making any rules, I just think people should be aware it. Otherwise there is a very real problem with going around in circles of abstractions and ending up back where you started for the single line of code you needed.
Does that sound fairer, on Java at least?
-
You can write Fortran in any language - and many people do. Don't damn English because Harold Robbins and Danielle Steele and Barbara Cartland used it as their tool!
Having said that, Java the language is suffering the usual fate of having extra things grafted on because they are fashionable in other environments.
I suppose we agree that it's not Java specifically at fault, but more how people have become dogmatized into using it in such a way. Not an attack of Java, but on how people implement OOP with it. Usually to the detriment of the actual functionality, IMHO. So often these engineers and I have worked with a lot of them, are more interested in satisfying some sort of fetish or religion on structure, abstraction, patterns. SOLID for example. Fine principles to have in the tool box, but writing every single tiny bit of functionality to be as generic as possible and plastering it with dogmatic patterns whether they are necessary or not.... has actually become such a grotesque caricature of OOPs intent it doesn't even resemble the "spirit" of it anymore. I honestly now ask people to count the number of lines in their code that has a tangible output and compare it against the total number of lines. I'm not making any rules, I just think people should be aware it. Otherwise there is a very real problem with going around in circles of abstractions and ending up back where you started for the single line of code you needed.
Does that sound fairer, on Java at least?
Oh yes - and on too many other languages and environments too :( Good taste is always at a premium, and there is always a tendency to degenerate into Cargo Cult Science/Engineering/Programming.
Of the SOLID principles, the Open-Closed and Liskov Substitution principles are pretty fundamental and easily applicable everywhere. The Single Responsibility and Interface Segregation principles are good concepts, but shouldn't be carried to extremes. The Dependency Inversion principle is useful at medium/large scale module boundaries, but not at a fine scale.
Overall, the Gang of Four Design Patterns were a good attempt at enabling thinking at a higher level. Noteworthy points: examples in different languages, and statements of where a pattern wasn't useful.
One concept that repeatedly emerges in computing is the attempt to get away from functions-invoking-functions being the fundamental composition mechanism towards something more like connecting hardware components via events and streaming. I've seen it many times, and in none of the cases was that concept even mentioned:
- Michael Jackson's Structured Programming in the early 80s was a set of steps that allowed manual transformation of procedural code into something vaguely composable like hardware
- Abelman and Sussman's classic "Structure and Interpretation of Computer Programs" did the same, but with streaming semantics
- the DIP, which is a codification of three Design Patterns: Factory, Abstract and Interface classes
- the various MicroService or Bean semantics that have been (?are?) fashionable