Can a class instance variable be excluded from a subclass in Java? - java

Possibly a dumb question, but pretend class Node has an instance variable called strength. And pretend class Episode, which extends Node, does not need strength (other subclasses do). Pretend also that there are a LOT of Episode nodes all storing an instance of strength. Is there any way in Java to say "this subclass does not have a strength variable"? I'm kind of seeing why this probably isn't allowed, but thought I'd check.
Update: Thanks all. As I suspected, the answer to this question is "no," but creating a subclass of Node with the variables/methods not needed by Episode, then connecting the other (sub)subclasses that need these variables/methods to that new subclass will do exactly what I want.

No, it's not possible. You can have e.g. Node and StrengthNode classes, one without strength and one with it, then Episode class will extend Node, others will extend StrengthNode.
Also, take into account the access control in Java, as if strength is a private variable in Node, it will not be accessible in Episode class directly (only using getter method), but it's instance will exist in memory anyway.

Well The only way i can think around this is if your problem with the size of the object your instance variable stores either you can initialize the parameter to null or you can serialize the object with specifiying your instance parameters to be transient and go with serialize it , deserialize it .
This was just a thought around that , cant think of anything closer.
if you specifically dont need exact inheritance you go around that with creating a custom factory and extract the member variable using reflection , that would work too.
Anyway thats my opinion.

Related

Studying Objects and Classes

I have a test later today, and I think I may be stuck on this part of the study guide:
Classes and objects, references, methods; the class as a pattern for
creating objects, the concept of a class and object as defining a unit
with data members and methods; what is an instance of a class; static
members of a class; what it means for a member of class to be public
My best effort to explain these concepts is, as follows:
A class is a programmer defined data type that is composed of data
members and methods.
An object is an entity consisting of values
(characteristics and traits) and methods (capabilities or behaviors).
A class is like a blueprint from which objects are created.
A reference variable points to an object created in another memory location. (not 100% sure what this means)
Much like a cookie cutter can be used to create individual cookies, a class can
be used to create individual objects, or instances of that class.
A static member of a class (or class variable or method) belongs
to the class and is not owned by any object of the class.
If a member of a class is public, that means that it can be accessed by other parts of the program.
I'm wondering if this is going to be satisfactory or if I'm missing anything critical. Obviously I'm shaky on the idea of reference and reference variables, and I think I'm still trying to conceptualize objects and classes in a way that's sufficiently explainable.
Thanks for your help, in advance.
A class is a template from which objects can be built; it acts as a blueprint for creating objects.
An object is an instance of a class.
Much like how an architect draws a blueprint of a house. The blueprint and constructed house are two different things. From that one blueprint, the same house can be built in a lot of places. Similarly, you can create multiple objects of a class.
The blueprint defines how a house is supposed to look like. There is going to be a kitchen, a couple of bedrooms, a basement (possibly for hiding illegal money), etc. Each person who buys a house will customize the house in a different way.
This is akin to values in an object - same variables in different objects may have different values.
Get it? Same bedroom in two different houses constructed from the same blueprint will have different color, bed, lighting, etc. Same thing, different value.
Here is how you understand static and instance variables. The kitchen belongs to everyone - it is static and is shared by everyone and only one kitchen exists (static). Your guitar belongs to you and you only, it is not shared with anyone but it may happen that you sister also has a guitar that belongs to her and her only.
What I am saying is - every object has its own copy of instance variables while there is only one copy of static variables that is shared by all the objects of that class.
Here is how to understand changing the values of static and instance variables
If you were to get custom graphics for your guitars, it will matter to you and you only because it is an instance variable. If there was some change made to the kitchen, say the fridge was moved, it affects everyone because kitchen is a static variable.
What I am saying is - changes to instance variables are only visible to the object that owns them while changes to static variables are visible to all the objects of that class.
Seems pretty spot-on to me. If I'm being pedantic, I'd recommend changing the last two sentences:
A static member of a class belongs to the class and is not owned by
any instance of the class.
If a member of a class is public, that means that it can be accessed
by other classes within the program.
To understand references, you also might want to read this: http://www.javaranch.com/campfire/StoryCups.jsp
And its follow-up: http://www.javaranch.com/campfire/StoryPassBy.jsp
You seem to have everything else nailed down pretty pat. For newbies, reference types and reference variables are continuous points of contention because they have a tendency to get confused with something else.
The easiest way to understand reference types is to compare it in terms of houses. Your house is the value, your street address is a pointer to your house (a reference), and your full address -- could -- be considered to be your reference variable when used on an envelope.
See what I did there?
For the most part, you seem to have the material down. I'm going to try and answer your implied question here,
A reference variable points to an object created in another memory location. (not 100% sure what this means)
A reference (in Java) is a bit like a po box number. You can go to the post office and find lots of po boxes, but the number makes the specific box easy to find. Also, it is unique within the post office. It ensures the mail is kept separate from the other boxes. The analogy is not perfect (note the key is largely immaterial to this discussion).
Yes you are spot on with classes and how objects are instances of them. A class is like a template that contains all the attributes/characteristics. Within a class, there can be objects, which are more of instances of the class. For an example, say there's a class called 'Animal'. That means whatever items are in the class all have one thing in common: they're animals. Now, an object of the class 'Animal' would be a specific animal (bird, elephant, giraffe, dog). These would be objects under the class 'Animal' because they're all animals, but they're objects because they are instances of animals (kinds of animals). Also, when a member/method of a class is public, it can be accessed by other parts of the program or project. Hope this helps.

Java serialization: static variables not serializable: workaround

Ok, so this question is mostly just related to: is there a better way to do this?
I have a phonebook application, and you can add users to it, delete them, and such, with each person being assigned a distinct ID#. A Person class stores lastIDused as a static class variable. The phonebook class has a vector of Persons.
My workaround thought is this: create a new non-static variable for the Person class, and upon serializing/saving, for the 1st element in the vector only, store the static variable's data into this new variable. Then, when de-serializing, re-set the static variable using the 1st Person's such-variable.
Going back to my original question: is there a better/more-formal/proper way to do this?
A better solution (IMO) would be to make lastIdUsed an instance field of the PhoneBook class. It sounds like you are already serializing an instance of that class ...
FWIW - making lastIdUsed an instance field of Person is just bad object modelling. The field is almost never going to be useful and almost never going to have a valid value. It will only have a valid value in the case of the first serialized Person in a PhoneBook.
First, I would avoid this kind of thing entirely. Static variables aren't serializable for a reason, namely by deserializing something you would invalidate the state of other objects. For example, if your lastUsedId is at 10 and you deserialize an object where it was at 5, it could lead to creating duplicates (6-10).
However, if you are still going to do this, check out the Externalizable interface. It lets you control the serialization and deserialization of an object. Here[1] is a good discussion on it. In the past I've used Externalizable to more tightly control the format of the object being serialized in order to save space. If you really want to, you could serialize a static variable and set it when you deserialize. You could even only set it if it is higher than the value currently in memory. Again, like other commenters I would advise against this approach entirely, but it doesn't hurt to learn this stuff, eh?
[1] What is the difference between Serializable and Externalizable in Java?

Generalized nested for loops

Say you have a set of objects that are arranged into a hierarchy. That is, there is an all encompassing object, then that object refers to several objects of the same kind but at a lower level, and each of those objects refer to several objects of the same kind but of a lower level, and so on for a variable number of steps. For example sake, lets consider these objects to be governments, so the highest level would be global, then global would have countries, and tribes, and countries would have towns, and towns would have houses, and businesses ect. All these governments extend the gov abstract class, so they all share the same kind.
I need to iterate through all the objects in the whole hierarchy, but because I don't know the complete structure at run-time, I have to do it in a generalized fashion.I only know for certain that there is a Global government, and then I have to check what sub-governments it has to proceed.
One way I'v found to do it is to give the super class a function called getSubGovs() which returns a list of all it's sub governments plus what each of those sub governments return from getSubGovs(). I hope that makes sense. It's a nice way to recurs through the problem.
What I'm looking for is a way to do this without having to add a function to the super class, for the case where I'm dealing with an API and cannot modify the super class. What would be an elegant way to do that?
This kind of structure is called a tree
Normally, every tree node has the same type, which has a getChildren() method or similar - in your case getSubGovs(). It sounds like each class has its own way of getting the children, so a straightforward abstraction is not possible.
The standard software pattern to apply that can navigate the tree in a generalised way is the visitor pattern, but because you can't modify the classes, you may need the facade pattern too.
I'm not 100% certain about what you want to achieve, but I believe what you would want here is polymorphism, namely inheritance and virtual functions (I dunno which language you are using but C++, for example, supports this).
Basically, you would make Global government the base class, and all your other classes the derived classes which would inherit Global government (or each other). Through inheritance you can establish the hierarchy you want (for example, by making classes lower in the hierarchy inherit from classes higher up in the hierarchy).
This page covers inheritance:
http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
Now for the iterative part:
first, you declare functions/methods virtual (using the keyword virtual) in the base class (e.g. global government). The derived classes will overwrite this function and customize it however they want. Note that you do not need the virtual keyword in the derived classes.
Here is the cool part: while you are iterating through the mix of sub and super classes, you use the base class pointer for all. Even when you call the functions of derived classes from a base class pointer, because you declared the functions you need virtual, the C++ determines which version of the function to call based upon the type of the object pointed to by the pointer. This determination is made at runtime, therefore you don't even need to worry about which object in the hierarchy the pointer is pointing to.
This page covers virtual functions: http://en.wikipedia.org/wiki/Virtual_inheritance.
Hope this is the sort of thing you wanted.
EDIT:
According to this page:
How do you find all subclasses of a given class in Java?
There is no elegant method, you will have to look at every class on the classpath.

Instance Field Declaration in Java

I'm just getting the hang of OOP and have been playing around with Java a lot. One of the troubles I have is deciding whether I need a private instance field for a particular class. Is there a rule of thumb I should be using in terms of whether I need to make something a private instance field of not?
Thanks.
Well, ask yourself whether it's logically part of the state of an instance of the object. Is it something about the object which is valid for the whole lifetime of the object, or is it something which only applies during the course of a single method (in which case it should be a local variable)? Or is it actually applicable to the class itself (in which case it should be static)?
If you could give some examples where you aren't quite sure, that would help.
(Note that I've assumed that the choice here is the kind of variable - static, instance or local. Instance variables should pretty much always be private :)
If it´s a natural part of the object or something the object needs to perform some task on a regular basis then by all means make it an attribute. If it is a constant then you should make it a public class variable (or rather a constant :P). That is, declare it "public static final w/e"
Public instance variables are not used as often because it often leads to messier code. Think as previously stated of the instance variables (or attributes) as the objects state. It´s usualy clearer to change the objects state by performing operations on it rather than juggle publics around. Good luck.
"Avoid public fields except for constants. (Many of the examples in the tutorial use public fields. This may help to illustrate some points concisely, but is not recommended for production code.) Public fields tend to link you to a particular implementation and limit your flexibility in changing your code." Controlling Access to Members of a Class
When learning object-oriented programming, think of it as a way to model real-world concepts as code. Nouns become objects; and the actions done to, on or by the nouns become methods. Instance variables are the properties of those nouns. For instance if you have a class representing a Car, slamOnTheBreaks() would be a method the Driver would call to slam on the breaks, and a Car has some number of seats inside, right? So an instance variable would be int numberOfSeats;.
Think of instance variables on a need-to-know, need-to-change basis. By making numberOfSeats public, that would allow the Driver to change the number of seats in the car, which doesn't make any sense. They only need to know how many seats the car has, which they can find out when they get in the car, or rather, calling the method public int getNumberOfSeats().
As Danny mentioned, the story is different for constants. If a value is a constant, it will remain constant for the entire duration of the program's execution, so for example if you want Driver Bob to be the only Driver for all those Car and Truck objects you create, Bob had better be a.) accessible, a.k.a. public, so he can be in every Car and Truck (assuming no inheritance between Car and Truck), and b.) unable to change.

the use of private keyword

I am new to programming. I am learning Java now, there is something I am not really sure, that the use of private. Why programmer set the variable as private then write , getter and setter to access it. Why not put everything in public since we use it anyway.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
I found some code like this, and i saw the comment legal but bad. I don't understand why, please explain me.
The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.
So by declaring the field private you prevent a user from accessing the variable directly. By providing gettters and setters you control exactly how a user may control the variable.
The main reason to not just make the variable public in the first place is that if you did make it public, you would create more headaches later on.
For example, one programmer writes public getters and setters around a private member variable. Three months later, he needs to verify that the variable is never "set" to null. He adds in a check in the "setFoo(...)" method, and all attempts to set the variable will then be checked for "setting it to null". Case closed, and with little effort.
Another programmer realizes that putting in public getters and setters around a private member variable is violating the spirit of encapsulation, he sees the futility of the methods and decides to just make the member variable public. Perhaps this gains a bit of a performance boost, or perhaps the programmer just wants to "write it as it is used". Three months later, he needs to verify that the variable is never "set" to null. He scans every access to the variable, effectively searching through the entire code base, including all code that might be accessing the variable via reflection. This includes all 3rd party libraries which has extended his code, and all newly written modules which used his code after it was written. He then either modifies all calls to guarantee that the variable is never set to null. The case is never closed, because he can't effectively find all accesses to the exposed member, nor does he have access to all 3rd party source code. With imperfect knowledge of newly written modules, the survey is guaranteed to be incomplete. Finally he has no control over the future code which may access the public member, and that code may contain lines which set the member variable to null.
Of course the second programmer could then break all existing code by putting "get" and "set" methods around the variable and making it private, but hey, he could have done that three months earlier and saved himself the explanation of why he needed to break everyone else's code.
Call it what you will, but putting public "get" and "set" methods around a private member variable is defensive programming which has been brought about by many years (i.e. decades) of experience.
Anything public in your class is a contract with the users of the class. As you modify the class, you must maintain the contract. You can add to the contract (new methods, variables, etc.), but you can't remove from it. Idealy you want that contract to be as small as possible. It is useful to make everything private that you can. If you need direct access from package members, make it protected. Only make those things public which are required by your users.
Exposing variables means that you are contracting forever, to have that variable and allow users to modify it. As discussed above, you may find you need to invoke behaviour when a variable is accessed. This can be be done if you only contract for the getter and setter methods.
Many of the early Java classes have contracts which require them to be thread safe. This adds significant overhead in cases where only one thread can access the instance. Newer releases have new classes which duplicate or enhance the functionality but drop the syncronization. Hence StringBuilder was added and in most cases should be used instead of StringBuffer.
Its considered bad mainly because you loose control over who can change the value and what happens when the value changes.
In tiny application written by you for you it won't seem that important but as you start developing for larger and larger applications having control over who changes what and when becomes critical.
Imagine from your example above, you publish library as is, other people use it, then you decide you wanted to calculate another value in your bad class when the size changes ... suddenly the bad00 class has no way of knowing and you can't change it because other people rely on it.
Instead if you had a set method you could extend it to say
void SetSize(int newSize)
{
size = newSize;
DoCalculation;
}
You can extend the functionality without breaking other peoples reliance on you.
I highly recommend the book Effective Java, it contains a lot of useful information about how to write better programs in Java.
Your question is addressed in items 13 and 14 of that book:
Item 13: Minimize the accessibility of classes and members
Item 14: In public classes, use accessor methods, not public fields
You shouldn't allow implementations to alter your records directly. Providing getters and setters means that you have exact control over how variables get assigned or what gets returned, etc. The same thing goes for the code in your constructor. What if the setter does something special when you assign a value to size? This won't happen if you assign it directly.
It's a common pet-peeve of many programmers - Java code with private fields and public accessors and mutators. The effect is as you say, those fields might as well been public.
There are programming languages that voice for the other extreme, too. Look at Python; just about everything is public, to some extent.
These are different coding practices and a common thing programmers deal with every day. But in Java, here's my rule of thumb:
If the field is used purely as an attribute, both readable and writeable by anyone, make it public.
If the field is used internally only, use private. Provide a getter if you want read access, and provide a setter if you want write access.
There is a special case: sometimes, you want to process extra data when an attribute is accessed. In that case, you would provide both getters and setters, but inside these property functions, you would do more than just return - for example, if you want to track the number of times an attribute is read by other programs during an object's life time.
That's just a brief overview on access levels. If you're interested, also read up on protected access.
This is indeed used to hide the internal implementation. This also helps is providing extra bit of logic on your variables. Say you need to make sure that the value passed for a varable should not be 0/null, you can provide this logic in the set method. Also in the same way you can provide some logic while getting the value, say you have a object variable which is not initialised and you are accessing that object, in this case you cand provide the logic to null check for that object and always return an object.
C# programmers use this equally as much, or maybe more frequently than I see in Java. C# calls it properties where in Java it is accessors/mutators
For me it makes sense to have getter and setter methods to encapsulate the classes so that no class can change the instance variables of another class.
Okay. We are talking about Objects here. The real world objects. If they are not private,the user of your class is allowed to change. What if for a Circle class, and for the radius attribute/property of the Circle class, the user sets value as '0'. It doesn't make sense for a Circle to exist with radius as '0'. You can avoid such mistakes if you make your attributes private and give a setter method and in which and throw an Exception/Error (instructing the user ) that it is not allowed to create a Circle with radisu as '0'. Basically, the objects that are created out of your class - are meant to exist as you wished to have them exist. This is one of the ways to achieve it.
As stated earlier, the reason for making a variable private is to hide it from the outside. But if you make a getter AND a setter then you may as well make the variable itself public. If you find yourself later in a position that you made the wrong choice, then you must refactor your code from using the public variable into using the getter/setter which may not be a problem. But it can be a problem if other code, which you do not control, starts depending on your code. Then such a refactoring will break the other code. If you use getters and setters from the start you will reduce that risk in exchange for a little effort. So it depends on your situation.
It depends on who access these public variables. Most likely, only by people inside your company/team. Then it's trivial to refactor them into getters/setters when necessary. I say in this case, it's better to leave the variables public; unless you are forced to follow the java bean convention.
If you are writing a framework or a library intended for the public, then you shouldn't expose variables. It's impossible for you to change them into getters/setters later.
But the 2nd case is more rare than the first; people apply extremely unreasonable assumptions when it come to software engineer, as if they are not writing code, instead they are carving code in stone. And as if the whole world is watching while you code - in reality, nobody will ever read your code except yourself

Categories

Resources