Beginner doubt about access and methods

J

Jordi

Hello

I have a doubt about how to write classes.
I have written something like this:

-----------
/*
* Data.java
*/

import java.io.Serializable;

package com.me.myPackage;

// abstract class to create others based on this

abstract class Data implements Serializable {

// variables

private String aData;


String getData(String data) {
return aData;
}

void setData(String data) {
this.aData = data;
}

}

-------------

So when I write a class that extends the class Data, I must set those
variables with:
setData("blabla");

These methods may only be used by classes in its package

I avoided using public methods or public variables for this class and
its subclasses to increase security.
Is this a good point, or not?

I saw some people do things like this but I don't know if I am doing
well. Most people used private variables but public methods.

Thanks for any oppinion.

Jordi
 
T

Tom Hawtin

Jordi said:
abstract class Data implements Serializable {
^If you insert java.io. here,
you don't need the import clutter.

By making your class serialisable you are effectively opening up a
second interface onto the class. Try to avoid exposing the
implementation as much as practicable. So much grief had been caused by
adding implements Serializable without thinking further.
serialVersionUID should also be present.
private String aData;
^^^^^data would be more conventional
(and readable)
String getData(String data) {
^^^^^^^^^^^Don't need that.
So when I write a class that extends the class Data, I must set those
variables with:
setData("blabla");

In general, try to avoid inheritance. Not dogmatically, but if you don't
actually need it, then don't use it.
I avoided using public methods or public variables for this class and
its subclasses to increase security.
Is this a good point, or not?

What aspect of security is important to you?
I saw some people do things like this but I don't know if I am doing
well. Most people used private variables but public methods.

For the most part, stick with public and private. The default
(package-private) and protected are obscure and should rarely be used
(except for package-private on outer classes and interfaces).

The reason for making variables private is to encourage encapsulation.
If you then add get and set methods, you've destroyed most of the reason
for making the variable private. Prefer operations that make sense to
the interface, rather than exposing the implementation.

Tom Hawtin
 
L

Lew

Tom said:
The reason for making variables private is to encourage encapsulation.
If you then add get and set methods, you've destroyed most of the reason
for making the variable private. Prefer operations that make sense to
the interface, rather than exposing the implementation.

You've destroyed part of the reason, perhaps, but not most of it.

get and set methods are a standard idiom recognized by a bunch of frameworks,
such as JSF and JSTL, that make it possible for them to use Java classes
without developer configuration.

get and set methods hide the implementation of attributes while exposing the
attributes. They allow tricks like not even having a private variable for the
attribute.

get and set methods can be made final, preventing abuse of the instance
variable that might be possible by increasing its visibility.

get and set hide the implementation of an attribute rather than exposing it.

I am not saying that use of these methods is a be-all and end-all, but these
are motivations for the idiom.
 
M

Mark Space

Jordi wrote:

These methods may only be used by classes in its package

I avoided using public methods or public variables for this class and
its subclasses to increase security.
Is this a good point, or not?

So far, so good. Although for instance variables I prefer private.
> So when I write a class that extends the class Data, I must set those
> variables with:
> setData("blabla");
>

This I don't understand. Usually, an abstract class has abstract
methods. If all you are doing is setting instance variables, I think
you may need a regular class.

class MyData {
private String someData;
void setData( String s ) {
someData = s;
}
public static main( String [] args ) {
MyData datum = new MyData();
datum.setData( "blah" );
}
}

This is fine.
I saw some people do things like this but I don't know if I am doing
well. Most people used private variables but public methods.

Package private is fine, if that's what you want. I think it's a good
way to add structure and encapsulation to a package, while preventing
classes outside the package from getting at classes which they
shouldn't. I do prefer private instance variables, since I think that's
also good encapsulation.

My only concern is that I don't see why the class needs to be abstract,
and I don't see why it needs to implement Serializable. (You don't do
anything with Serializable in your example.)
 
J

Jordi

Hello,

thanks you all for the opinions.

I use Serializable because I need to send my objects through the
network in a bigger program that I have written.
You can forget about that detail.

I take note on making the methods final, as they will remain that way
on the classes that inherit this.

It is abstract because there will be no instance of this class.

I need to create near 20 or 30 classes based on one abstract class.

My reason to use inheritance is not to have to repeat 20 or 30 times
the same code, so all becomes really confusing. Is this right?

I need to set some variables each time I create the instances of
subclasses. This may be done simply with constructors.
I create the get and set methods for if I need to change some value .


Do you think this is right?

Jordi
 
L

Lew

Jordi said:
Hello,

thanks you all for the opinions.

I use Serializable because I need to send my objects through the
network in a bigger program that I have written.
You can forget about that detail.

But you can't. Pay attention to Tom Hawtin's advice about Serializable:
Read Joshua Bloch's chapters on the subject in /Effective Java/. There is a
lot to take care of if you make a class Serializable.
I take note on making the methods final, as they will remain that way
on the classes that inherit this.

That is a good thing. Remember not to invoke overridable methods from
constructors.
It is abstract because there will be no instance of this class.

I need to create near 20 or 30 classes based on one abstract class.

My reason to use inheritance is not to have to repeat 20 or 30 times
the same code, so all becomes really confusing. Is this right?

Maybe. If your analysis indicates that the 20 or 30 types /are-an/ instance
of the supertype, then inheritance is the way to implement that. Re-use of
common base functionality is a strong but not compelling argument in favor of
using inheritance.

Note that code duplication can be prevented without inheritance by using
composition, instead including a helper-class object to handle the common
functionality. For example, most situations that call for a collection, say a
Map, should use a Map instance member rather than inherit or implement Map.

Again, this is a topic well covered in /Effective Java/.
I need to set some variables each time I create the instances of
subclasses. This may be done simply with constructors.
I create the get and set methods for if I need to change some value .

Do you think this is right?

If you make the methods final, most likely. However, there is an argument in
favor of not having the setX() method, making the instance variable final, and
simply creating a new instance of the object if you need a new value. For one
thing, it can make your code much more efficient. For another, it prevents
override abuse. For a third, it simplifies concurrency issues.

This is called making the class "immutable", or more correctly, making all its
instances "immutable". (The term is approximate - as others have pointed out
elsethread, nothing is ever completely "immutable" in Java.)

The trick is whether your design calls for the methods to be overridable.

Another topic thoroughly covered in /Effective Java/.
 
L

Lew

Lew said:
The trick is whether your design calls for the methods to be overridable.

I am not sure what I meant by that. I was trying to say that whether to make
a class or some of its fields immutable is a matter of your analysis and the
essential nature of the type you're defining. It is always something to think
about.
 
T

Tom Hawtin

Lew said:
You've destroyed part of the reason, perhaps, but not most of it.

get and set methods are a standard idiom recognized by a bunch of
frameworks, such as JSF and JSTL, that make it possible for them to use
Java classes without developer configuration.

It would make little difference if they peeked and poked the fields
directly. They'd just be a lot less boilerplate.
get and set methods hide the implementation of attributes while exposing
the attributes. They allow tricks like not even having a private
variable for the attribute.

Isn't this a dupe of your last point?
get and set methods can be made final, preventing abuse of the instance
variable that might be possible by increasing its visibility.

Haven't you got that the wrong way around? You can't increase the
visibility of a field, but you can override (accessible) methods to make
them public.
get and set hide the implementation of an attribute rather than exposing
it.

For trivial cases you can do that. But if you leave it as the default
boilerplate, there is no point.

For non-trivial cases it gets more difficult. If you have a get and a
set for a JTextField, there isn't much you can do. Even if JTextField
were an interface, it wouldn't help much. That sort of thing happens in
real life, rather than noddy examples.


I'm not saying that there is no merit in adding get and set boilerplate
instead of having public fields. I'm saying that the big win is in
having coherently designed interfaces.

Tom Hawtin
 
J

Jordi

Thanks Lew.

I do need to serialize the class.
Maybe I don't need to implement Serializable in the abstract class,
but the subclasses will use it as I need to send them through a Object
Stream and then to a byte array thru NIO, as I have my system now
developed.

The classes I am writting are objects that contain data to be sent
thru the net, so all them need this.

If I don't make Serializable the subclasses, they won't work for what
I need.

I have not read that book. Is there some resume in internet?

Maybe I should remove the Serializable from the abstract class?


Thanks again.

Jordi R Cardona
 
T

Tom Hawtin

Jordi said:
I have not read that book. Is there some resume in internet?

The bullet points from that book [Effective Java] and some discussion
are here:

http://www.java.net/cs/user/forum/cs_disc/1768

It's worth getting, but note there is a new edition out at some point.
Maybe I should remove the Serializable from the abstract class?

The base class will need to be serialisable if you expect it to look
after its own data. Subclasses can manage it by implementing readObject
and writeObject methods. However, if you use readFields/writeFields
(which would be the most natural way of storing the data), you run into
problems using final fields.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top