Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

OO in terms of Java  RSS feed

 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm having trouble understanding Java's depiction of OO concepts. Since Java is my first OO language, I can't really compare its depiction of OO to those of other languages.
I'm trying to make sense of inheritance and polymorphism in terms of the Java language specification, but so far I've failed.

Here is how I think generally:
1. A class is a blueprint from which one may create one or more separate objects.
2. The variables stored in and the methods invoked on an object of a class are members of that class.
3. A subclass inherits all members of its parent class.
4. A member's access modifier dictates where the member is accessible.
5. Whether a member is known to a subclass or not, is subject to inheritance rules. (I feel uncertain here...)
6. Overriding the method of an object means "replacing" the implmentation: the overriden method is no longer a member of the object. (I feel uncertain here...)

Here is how I think in terms of Java:
1. A class is a reference type, that can be used to construct objects and declare reference variables.
2. Members of a class are those that are inherited or declared in the body of the class.
3. A subclass only inherits public and protected members of its parent class, and package-private members if the subclass is in the same package as the parent class is.
4. A member's access modifier dictates where the member is accessible.
5. If a method overrides another one, which could be inherited and has same signature, then the latter is not inherited.

My confusion arises because the way Java depicts OO is unnatural and difficult to grasp.
Anyway, is my general OO model acceptable?
Where can I read in detail about OO?

I want to be comfortable with inheritance to the point where I have no trouble conceiving a more-or-less long hierarchy.
Basically, I want to be comfortable with OO.

I'm posting this because I want to immediately start programming Android apps, but I'm feeling very frustrated over these fundamental concepts.
Thanks.
 
Fred Kleinschmidt
Bartender
Posts: 560
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A subclass only inherits public and protected members of its parent class, and package-private members if the subclass is in the same package as the parent class is.


No, a subclass inherits all members of its superclass. It is just that the private members are not directly accessible. For example, a JPanel inherits background from its superclass hierarchy (it is actually a member of Component). You cannot access background directly from a JPanel instance, but you can access it via the getBackground() and setBackground() methods.
 
Stephan van Hulst
Saloon Keeper
Posts: 7817
142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fred Kleinschmidt wrote:No, a subclass inherits all members of its superclass. It is just that the private members are not directly accessible. For example, a JPanel inherits background from its superclass hierarchy (it is actually a member of Component). You cannot access background directly from a JPanel instance, but you can access it via the getBackground() and setBackground() methods.

This is not correct. From the JLS:
Members of a class that are declared private are not inherited by subclasses of that class.

Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.

Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16028
87
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you have the basics correct.

Ramsin Khoshaba wrote:My confusion arises because the way Java depicts OO is unnatural and difficult to grasp.

Can you explain in more detail how exactly you think OO works in Java is unnatural and difficult? Are there specific ways in which Java works differently than you expected?

One of the most important concepts to understand is that there is an "is a" relationship from subclass to superclass, and subclassing means specialization. In other words: an instance of a subclass is a (special version of) an instance of a superclass. This is called the Liskov substitution principle.

Think, for example, about a class Animal and a class Lion extends Animal. A Lion is a specific kind of Animal.

Some books and tutorials present examples with class Parent, and class Child extends Parent. That's wrong and confuses the biological meaning of inheritance with what inheritance means in OO programming. Inheritance means something different in OO programming than in biology. So, don't let yourself be confused by this. If you have class Parent and class Child extends Parent, what that really means is that a Child is a special kind of Parent, which is obviously wrong.

Wikipedia has a lot of information on object-oriented programming.
 
Fred Kleinschmidt
Bartender
Posts: 560
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is really a nit about symantics for the word "inherit". I contend that when I call myPanel.setBackground() it sets the background member of Container.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you call that nitpicking then you will have to take it up with the designers of the language. The JLS, as Stephan has told you, is very precise about that. Such precision is essential for language specifications, but it makes them difficult to read. No, private members are not inherited by subclasses.

And if you unzip the source code, you will find that background is not a member of JPanel nor or JComponent; it is a member of java.awt.Component, inherited by java.awt.Container but not inherited by JComponent because it has package‑private access in the AWT package. The set and get methods have public access and are therefore inherited (overridden in JComponent), as you can see from the API documentation.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fred Kleinschmidt wrote:This is really a nit about symantics for the word "inherit". I contend that when I call myPanel.setBackground() it sets the background member of Container.

No it isn't, and you could well be wrong. What you're describing is behaviour; not mechanics. You're assuming an implementation akin to C++, where the memory for a subclass object is mapped according to certain rules - one of which being that it contains the memory map of its superclass - whereas the JLS doesn't specify any such thing.

Furthermore, item 2.7 of the JVM spec clearly states as its opening gambit:
  The Java Virtual Machine does not mandate any particular internal structure for objects. (my emphasis)
and in such a set-up it would seem wasteful to carry around private variables as "excess baggage".

You are right about one thing though: when it comes to methods, "inheritance" is all about visibility, because it's highly likely that ALL methods are actually attached to the class, not an instance.

Winston
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First: Thanks Ramsin for a thoughtful and well-written question that I think deserves a cow.

Now to tackle some of your questions:

1. Inheritance is only one way of defining complex objects, and current thinking seems to be moving away from strict ("is-a") hierarchies towards decorative ("has-a") ones.
The fact is that the LSP Jesper mentioned is "broken" by one of the very first methods you learn about: (equals()) almost as soon as you start constructing hierarchies; so I wouldn't plan on making too many "deep" ones just yet.

The power of "objects" comes not from being able to create hierarchies - which is really just a form of shorthand - but in being able to create things that interact with each other in a really dynamic way.

2.
My confusion arises because the way Java depicts OO is unnatural and difficult to grasp.

And part of that may be because Java is a "hybrid" language. It allows you to define classes and objects, but doesn't require you to; and much of the code you write - especially when you're starting out - has nothing to do with OO. It's strictly procedural.

3.
I want to be comfortable with inheritance to the point where I have no trouble conceiving a more-or-less long hierarchy.
Basically, I want to be comfortable with OO.

And that, I hate to say, will take time - in my case: 7 years - but that doesn't mean that you can't write some good stuff in the meantime. Have a look at what Peter Norvig has to say about it - it'll either put you off completely, or brace you for the challenge ahead (hopefully the latter ).
You might also be interested in my MomentOfClarity.

4.
I'm posting this because I want to immediately start programming Android apps, but I'm feeling very frustrated over these fundamental concepts.

Well, hopefully Peter Norvig has shown you that nothing is going to happen immediately; but if you're absolutely set on doing this, download the Android JDK/toolkit and get to it. We aren't going anywhere, and we even have an Android forum if you run into trouble.

My advice though: Learn to walk first; then you'll find running a bit easier.

HIH

Winston
 
Fred Kleinschmidt
Bartender
Posts: 560
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is interesting that the JLS and Oracle's Java Tutorials differ in what they say about what is inherited. From the Java tutorial,

Inheritance


In the preceding lessons, you have seen inheritance mentioned several times. In the Java language, classes can be derived from other classes, thereby inheriting fields and methods from those classes.


Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class). The class from which the subclass is derived is called a superclass (also a base class or a parent class).

Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.

Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object.

The idea of inheritance is simple but powerful: When you want to create a new class and there is already a class that includes some of the code that you want, you can derive your new class from the existing class. In doing this, you can reuse the fields and methods of the existing class without having to write (and debug!) them yourself.

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.


Note the last sentence does not qualify fields as to private or not; it merely states that all members are inherited.
 
Tony Docherty
Bartender
Posts: 3268
82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Java tutorial unfortunately contains errors and it looks like you have found one of them.
 
Joe Bishara
Ranch Hand
Posts: 175
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A subclass inherits all the members (fields, methods, and nested classes) from its superclass.

I think that the statement is saying that whatever a subclass inherits (fields, methods, and nested classes), it inherits from its superclass. But I agree. The tutorial could have made things a little clearer.

Nevertheless, the tutorial does say

A subclass does not inherit the private members of its parent class.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fred Kleinschmidt wrote:. . . the JLS and Oracle's Java Tutorials differ in what they say . . .
In all instances where there is a discrepancy, the JLS is definitive.
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your comments. I read Norvig's article and I agree with him: I have not read other people's code; I have not been in a working environment; and I have not really developed "cool" or useful applications.

The way of achieving inheritance (as a specializtion) can be understood in a different way in each language, I think. I believe I need to dig deeper than the informal mammal-dog explanation, and yet not so deep to the implementation level where everything is left to interpretation. Also, if the inheritance mechanism represents a specialization, then isn't it a design flaw to extend for example JFrame for the sole purpose of customization or adjustment?

What does membership, i.e. being a member, in Java exactly correspond to in the real world? (Let's pretend the default access modifier does not exist for a moment.) I've had thoughts about whether private members should be only used for the internal implementation of an object; private members should not correspond to attributes of the object being modeled, rather to the internal functionality which makes the object functional in the first place. If that is the case, then an age field in a generic Person class should be made protected, so it can be inherited; age does not involve the internal details of a Person object, to make it functional. As said, it's just a thought...

If the preceding paragraph is totally incorrect (or literally absurd), then matters get more complicated (at least for me). What I meant by saying that OO in terms of Java is being unnatural and difficult, is that private fields of a superclass are still "members" in some way of an object of the subclass. Here is the dictionary definition of member:
"In object-oriented programming, a function or piece of data associated with each separate instance of a class."
If age is declared private in Person, then age is still a "member" of an instance of Employee, at least according to the dictionary definition.

If I have the following,


A.i is not visible, because i is not inherited by b.B and therefore i is not a member of C.
But (according to the above dictionary definition) i is a member of an instance of C; therefore, I find it (equally) difficult to explain inheritance in terms of the dictionary definition of member.

I am confused. :/
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . What does membership, i.e. being a member, in Java exactly correspond to in the real world? . . .
Why does such a concept have to have a real‑world counterpart? Why should any real‑world counterpart have to correspond exactly to Java®?
I've had thoughts about whether private members should be only used for the internal implementation of an object; private members should not correspond to attributes of the object being modeled, . . .
Do you mean members or methods?

There is information about me; I carry round some information which is inside me. I have for example a name which I know and it belongs to me, like a private field. I don't allow other people access to it to change it. I do however have a sort‑of
public Name getName()
method which means that somebody can ask my name and I tell them.
I also have private methods myself; there are things I do without allowing other people access to them, e.g. washing.

Private fields refer to the data inside an object; if those data are to be made available to the outside world, then methods should be provided for that. The private fields are not inherited if there are any subclasses; the public methods are however inherited if the class is extended.
There may be private methods which are used for internal manipulation of the object's state. Things I do alone when nobody else is watching are like private methods. But I can assure you that if you start thinking too hard about things people do in real life and access to methods, the analogy will break down very very quickly.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . If I have the following, . . . A.i is not visible, because i is not inherited by b.B and therefore i is not a member of C.
Correct. Because the field i has package‑private access (=unofficial but useful name for default access), it cannot be inherited by a class in package b.
But (according to the above dictionary definition) i is a member of an instance of C . . .
Please tell us where you got that “dictionary definition” from, so we can have a look at it and decide whether it is incorrect. A programming language has its own “dictionary definitions”, and in the case of Java®, those are in the Java® Language Specification (=JLS). If the definitions differ, then the JLS provides the “correct” definition, and you must disregard the other definitions.

Beware: that is only one part of the JLS, and the JLS can be difficult to understand.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Any access to a field in a class should be organised within the class with the field. Why should subclasses have to organise their own access? If you have an age field in a Person class, that field should be manipulated within the Person class. Whoever writes the subclasses does not need to know how to handle the age field; all they need to know is that the age field changes whenever you have a birthday. They need no information about to how it changes. If that is done via method accessible in subclasses, that is sufficient. It should be unusual for a subclass to need to do things differently; that is when you override methods.

General principle of OO programming: keep all your data (=fields) hidden but consider providing easily accessible means to access or alter the data (=methods).
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Please tell us where you got that “dictionary definition” from, so we can have a look at it and decide whether it is incorrect. A programming language has its own “dictionary definitions”, and in the case of Java®, those are in the Java® Language Specification (=JLS). If the definitions differ, then the JLS provides the “correct” definition, and you must disregard the other definitions.

https://en.wiktionary.org/wiki/member

I cannot find some definitions (such as a definition for member) in JLS.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You will find a list of declared members here in the JLS. You should find out about inheritance here or similar.
There is no discrepancy between the two definitions because that in Wikipedia is vague so as to avoid such discrepancies. It says function or piece of data but does not say which Java® pieces of data are or are not members.
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Whenever a new instance of a class is created (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.1.1

"Members of a class that are declared private are not inherited by subclasses of that class."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2

My professor has told me that everything is inherited, i.e. even private members of a superclass are members of its subclass! I think confusion arises because of the way people think of members; I'm inclined to think of a (instance) member of a class as a property that belongs to every object of that class. For example, every person has a name and so does every employee. So if I have some Person class in which 'String name' is private, and some Employee subclass; then I naturally consider 'name' to also be a member of Employee. That was what I meant when I said Java made OO difficult and unnatural. I have not studied other OO languages, so I cannot compare either.

However, should 'name' be declared protected, according to good design?!
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . should 'name' be declared protected, according to good design?!
No.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suspect you are confusing things. Yes, when you instantiate a class to create an object, then one object is created. If you create an Employee instance, that will have a name field somewhere pointing to a Name instance. The name field is in that part of the object which is created from the Person class.

But in the other link, it says that fields are members of a class, not members of an object. That is different. The private name field is a member of the superclass only. You do not talk about members of an object. But there is a name field in there. It should be private to the Person class, which means that it is not directly accessible to the subclass (Employee) and is not a member of Employee. You can make that field accessible to the subclass with non‑private getXXX or setXXX methods.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:My professor has told me that everything is inherited, i.e. even private members of a superclass are members of its subclass!

No they aren't. And if that is indeed what your professor said, then I disagree with him on two counts:

1. It contradicts the JLS.
2. Inheritance is dependent on visibility. Again from the JLS:
"...A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class..." (my emphasis).

I suspect that your professor is thinking of the C++ model, where the memory footprint of a subclass is clearly defined, and does include a copy of its superclass. Now it's perfectly possible that some - or even most - JVMs do things the same way; but I'm pretty sure it's not required.

And might it not actually save space if a subclass instance simply contained a pointer to its superclass, rather than a copy of it? Then a clever compiler (and compilers are pretty clever these days) might be able to save a lot of space by telling the JVM to only create one instance of a superclass in cases where it knows it can't be modified.

HIH

Winston
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . Java made OO difficult and unnatural. . . .
There is nothing difficult about the Java® version of OO. There is something difficult about every version of OO, not only Java®. It is one of those things about programming you will have to learn. It may take a long time to learn but once learnt it will provide you with a valuable skill.
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Should I think of a class as a reference type, instead of as a set (or category)?

If yes, then a value of a class is a reference. That is, a variable of type MyClass may store a value of type MyClass, or null. This value may be converted to a superclass type, and still reference an object of type MyClass.

Instance attributes and actions that may be accessed through a value of class T are said to be members of class T.

An instance method m() visible to class T is a member of T. Overriding from subclass C the otherwise-inherited method m() gives rise to a new member method m() of class C. Overriding means replacing the implementation of an overridden method.

Only methods that would otherwise be inherited can be overridden.

I'm still not sure though why e.g. private methods or uninherited methods with default access cannot be overridden.

Am I on the right track?!
Sorry if I seem to be in a rush... I'm a bit perfectionist, plus I'm applying for a student part-time job.
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:Should I think of a class as a reference type, instead of as a set (or category)?

If yes, then a value of a class is a reference.
No, the value of a class is a class. What you describe later is a variable, which should hold an instance of that class. Or more precisely a reference to an instance. Classes are called reference types and Java® doesn't have the concept that classes represent categories or sets, which some other languages, e.g. B, RVM_Forth, RuthR, do. You probably haven't heard of those languages.
That is, a variable of type MyClass may store a value of type MyClass, or null. This value may be converted to a superclass type, and still reference an object of type MyClass.
You cannot convert the types of objects. Once an object has a particular type, it retains that type for ever. But most objects have several types. Your Employee object is also a Person object and an Object object. If you make your class implement an interface, e.g. Comparable, then its instances are also Comparable objects. You can cast the reference to any type which the instance is already; if you try to cast to the wrong type you will get an error, maybe at compile‑time or maybe at runtime (in which case it is visible because you suffer a class cast exception).
Instance attributes and actions that may be accessed through a value of class T are said to be members of class T.
What about static members?
An instance method m() visible to class T is a member of T. Overriding from subclass C the otherwise-inherited method m() gives rise to a new member method m() of class C. Overriding means replacing the implementation of an overridden method.
That only applies to instance methods. You can hide static methods but not override them, and that can lead to a lot of confusion.
Only methods that would otherwise be inherited can be overridden.

I'm still not sure though why e.g. private methods or uninherited methods with default access cannot be overridden.
They do not exist in the subclass, so the compiler sees the methods you write as “new” methods.
Am I on the right track?!
Yes
Sorry if I seem to be in a rush... I'm a bit perfectionist, plus I'm applying for a student part-time job.
And good luck with the application.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:Should I think of a class as a reference type, instead of as a set (or category)?

I find it best to think of it as a blueprint.

If I want to make a table - or a car, or a widget - for mass-production, I first need to explain to the people that are going to make it what it looks like (height, width, number of legs...etc). So it you think of your program as an object factory, you first need to explain to Java what your objects are going to look like. And that's your class.

The fact is that Java stores that information in a class of its own, called Class. And that IS a reference type.

The only other types that Java supports are primitives: int, long, boolean etc; and you can tell one from the other by the fact that reference types start with a Capital letter - something you should definitely remember to do with your own classes.

I'm still not sure though why e.g. private methods or uninherited methods with default access cannot be overridden.

Hopefully, Campbell's covered that one; but if you still have problems, feel free to ask again.

Sorry if I seem to be in a rush... I'm a bit perfectionist...

And I'm afraid that those two things don't usually go well together:
Good, fast, cheap - pick any two.

plus I'm applying for a student part-time job.

Best of luck with it - and thanks for a great thread!

Winston
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason I said a value of a class was a reference, is the following:

"The types of the Java programming language are divided into two categories: primitive types and reference types. [...] The reference types (§4.3) are class types, interface types, and array types. There is also a special null type. An object (§4.3.1) is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects." https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html

"A widening reference conversion exists from any reference type S to any reference type T, provided S is a subtype (§4.10) of T." https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5

OBS! In Java's terms an instance is an object; I use the word "instance" in a different meaning below.
An int literal designates an instance (or value) of type int. A double literal designates a double instance. Likewise, since classes are reference types, an object creation expression evaluates to an instance (or value) of the corresponding class type, the value of which is a reference.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:OBS! In Java's terms an instance is an object;

Actually, it's usually the other way around: An object is an instance (of a class or type).

I'm also not quite sure what 'OBS' means - and nothng jumps out here.

Winston
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I meant observe.
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello again,

Campbell Ritchie wrote:But in the other link, it says that fields are members of a class, not members of an object. That is different. The private name field is a member of the superclass only. You do not talk about members of an object. But there is a name field in there. It should be private to the Person class, which means that it is not directly accessible to the subclass (Employee) and is not a member of Employee.

As opposed to a member of an object, could you define a member of a class explicitly? What a member of a class is?

Winston Gutkowski wrote:2. Inheritance is dependent on visibility. Again from the JLS:
"...A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class..." (my emphasis).

So being dependent on visibility does not mean being defined in terms of visibility, right?

I believe this is an important topic. There are many teachers who teach member inheritance in terms of accessiblity: private members are inherited but not accessible to subclasses, for example. And yet I can't easily find discussions on the distinction between the just-mentioned description of inheritance and how JLS describes inheritance.

If I have this code (again):


Obviously (using the other model/explanation) B inherits A.i but has no access to it. Then C inherits A.i (which is declared in the same package as C) but has no access to it. This model (at least apparently) is somehow incomplete. A.i is declared with default access but still inaccessible to C. Whereas, conforming to JLS, A.i is not inherited in the first place, so it's not a member of C, even though it's a "member" of an object of type C. For some languages, such as PHP, it seems consistent to use the other model. Because PHP has no packages, and private methods are implicitly final anyway. I still don't understand the JLS.

Btw, thanks for your time...
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . There are many teachers who teach member inheritance in terms of accessiblity: private members are inherited but not accessible to subclasses, for example. // . . .
As Winston has already told you, obviously whoever teaches that sort of thing is mistaken.

// . . .
Right. You have a package‑private field i. Remember that is different from a private field. As you correctly surmise, that is not a member of class B and is not inherited so you cannot find it, because B is in a different package. It would be much easier to understand if you gave “real” names to your classes and packages rather than one‑letter names. Even though your other two classes are in the same package, you are calling things outwith your current package, so i doesn't exist, so the compiler cannot find i and the code won't compile. Because i is not inherited by class B, it cannot appear in C. Try adding a constructor to B like this:-Again, that should fail to compile.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:Whereas, conforming to JLS, A.i is not inherited in the first place, so it's not a member of C, even though it's a "member" of an object of type C. For some languages, such as PHP, it seems consistent to use the other model. Because PHP has no packages, and private methods are implicitly final anyway. I still don't understand the JLS.

And I'm afraid that's just how it is with languages. It's very possible that your code above would work in C++ because of the way it defines class memory, but Java simply doesn't do things that way. I have to admit being quite surprised about PHP because I thought it was based on Java, but there you go...

Btw, thanks for your time...

You're most welcome. Fun thread.

Winston
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Fun thread.

Quite!

Fred's excerpt from the tutorials that misstates inheritance is an interesting choice, as the the same tutorial gets it right, a little farther down the page:
Oracle wrote:A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent.
...
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.


And Winston's sagacity shows again, as he points out that no particular implemention need be implied (nor can be assumed) by the existence of a property setter or getter: they may be assigning/returning the value of a private member field, or they may be invoking substantial computation. For example, if my Rectangle class has a getHeight() method, a getWidth() method, and a getArea() method, those can be fully implemented with my class only retaining two of those three values as private members (and computing the third value from the other two, when any client needs it). Indeed, I can even change which private members my class retains, and how those three methods are coded, and clients of my class will never know, care, nor have to change their code to keep on using my class.

Ramsin's questions and observations have me wanting to ask a related question that I've been wanting to bring up for a while, and that I hope is on-topic: In addition to the Liskov Substitution Principle, there are a number of widely respected axioms about OO, such as, "A class should be open for extension, but closed for modification," "Favor composition over inheritance," "Encapsulate what varies," "Code to an interface, not to an implementation," and so on. My question is, is there a site with God's List of these axioms?
 
Campbell Ritchie
Marshal
Posts: 55751
163
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The two tablets of stone have unfortunately been lost. They had the ten commandments on one side and the SOLID principles on the other. O is the first thing you quoted. Before that you had named L. A lot of people no longer fully believe in O.
 
Stevens Miller
Bartender
Posts: 1444
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:The two tablets of stone have unfortunately been lost.


No they haven't. My in-laws told me they're being used to press copies of The New York Times .

They had the ten commandments on one side and the SOLID principles on the other. O is the first thing you quoted. Before that you had named L. A lot of people no longer fully believe in O.


Yeah, SOLID is the core. And I'm not really looking for gospel, just more good rules of thumb. There seem to a number of them that I encounter so repeatedly, that I'm wondering if there isn't a single site or resource where most (if not all) of the more commonly respected ones are gathered.

I admit, when I read O for the first time, I thought it had an implicit question built into it that, ultimately, made it infirm: When should a class be closed for modification? After it has been compiled without error for the first time? After it has been used in a library? In an application? After it has been published for use by others outside the publishing entity? What if a fundamental bug is discovered, such that the existing interface is dangerous to use (Thread.stop, anyone?)?

But, even allowing for the fact that we, as imperfect corporeal beings, do not create divine writ, I'd like to know what others have found useful as, say, the short list of guidelines.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:But, even allowing for the fact that we, as imperfect corporeal beings, do not create divine writ, I'd like to know what others have found useful as, say, the short list of guidelines.

Here's a few of mine. You'll probably recognise most of them as paraphrased chapter headings from Josh or well-known articles, and they're Java-centric. I've tried not to include any SOLID or GRASP stuff:

1. Write dumb code.
2. Fail fast, and fail LOUD.
3. Tell, don't ask.
4. final is your friend.
5. Use interfaces, but consider skeleton implementations.
6. Use generics.
7. Don't overuse generics (ie, don't expect it to solve all your typing problems).
8. Don't let the compiler write things for you.
9. Almost all implementations of equals() are wrong.   Also:
  • Don't make equals() any more LSP-hostile than it needs to be.
  • 10. Make compareTo() consistent with equals().   Also:
  • Have a comparison policy for null, even if it's just to throw NPE.
  • 11. Favour fluency (ie, embrace lambdas and streams, and consider returning this instead of void).
    12. Persistence is futile.

    Obviously that last one isn't meant to be taken literally, I just thought it was catchy. Basically what it's saying is: "be aware of the object/relational mismatch, and plan for it early".

    And with many of them you can add "unless you have a good reason not to".

    Winston
     
    Campbell Ritchie
    Marshal
    Posts: 55751
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    How much evidence is there for Odersky Spoon and Venners to argue that so many implementations of equals are wrong? If you look in other sources, e.g. Angelika Langer, she doesn't say that anything like that many implementations are wrong. She does show some bad examples however.
    And you can get as much heat rather than light about whether to throw NPE or a different Exception. Nearly as good as spaces vs tabs for indenting
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!