I am a newbie in Android programming and have little confusion in following code.
This portion of code is from android developer site:
public final class FeedReaderContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public FeedReaderContract() {}
/* Inner class that defines the table contents */
public static abstract class FeedEntry implements BaseColumns {
public static final String TABLE_NAME = "entry";
public static final String COLUMN_NAME_ENTRY_ID = "entryid";
public static final String COLUMN_NAME_TITLE = "title";
public static final String COLUMN_NAME_SUBTITLE = "subtitle";
...
}
}
I read some articles about nested classes in Java documentation and some other blogs and understood following reasons to use nested class:
Provides better encapsulation.
If a class is concerned with only one another class, then we better would make nested class of these two.
But here, I could not figure out anything to use nested class.
What exactly is the purpose of making nested class?
This particular nested class is used as a namespace for String constants related to its main class.
It is abstract, so it's not intended for instantiation
It implements BaseColumns interface, which is essentially a way to "dump" string constants into the FeedEntry class
Why did they used nested class instead of free-standing class?
Use of a nested class underscores "semantic closeness" of the inner class to its outer class. It cnveys to the readers of your code that FeedEntry can be interpreted only in the context of FeedReaderContract. Otherwise, FeedEntry is meaningless. Essentially, this is done for the human readers of code, because in this case there would be no difference to the compiler.
Related
I have an abstract class that has some constants that each child class will use. Each one of them is static, final and immutable.
public abstract class MyAbstract {
//some private instance fields
protected static final long LONG_ID = 1;
protected static final String STRING_ID = "example_id";
//some methods
}
I know that having protected static final is bad practice but what about protected static finals that are immutable?
I know that I can make them public but I'd like to avoid doing so as the constants refer to specific ID's that user doesn't need to know.
To answer your question in the title "What is the best practice of inheriting constants in Java?", my answer is: do not inherit them at all.
Inheritance has a special meaning and purpose in object oriented programming, and using inheritance just for convenience because you want to be able to access constants in a particular set of classes does not correspond to this meaning and purpose.
If you have constants that you want to be able to use in different classes, you can put the constants in a separate class. Make this class final and make the constructor private so that it can't be subclassed and instantiated:
package com.example;
public final class Constants {
public static final long LONG_ID = 1L;
public static final String STRING_ID = "example_id";
// Private constructor, this class should not be instantiated
private Constants() {
}
}
Then, in a class where you want to use the constants, use import static:
import static com.example.Constants.LONG_ID;
public class Example {
public void someMethod() {
// Use the constant
long id = LONG_ID;
System.out.println(id);
}
}
The advantage is that the class Example does not need to extend class Constants or implement an interface, so you do not need to misuse inheritance, while you still have the same convenience of being able to use the constants with concise syntax.
i have this code :
package com.example.android.cars.data;
public final class DataBaseContract {
public static final class Table1Entry implements BaseColumns {
/** Name of database table for cars */
public final static String TABLE_NAME = "car";
}
}
i use Table1Entry in another class with different package and i import the nested class like this
import com.example.android.cars.data.DataBaseContract.Table1Entry;
this allow me to use nested class without outer prefix DataBaseContract,
my question is when i removed static from nested class the code still work, how can this accrue in this case !! i need outer instance to access it!!
Yes you would need an instance of the outerclass IF you wanted to access instance methods of the inner class. However from your example you are only accessing static fields, therefore because the field is static you can access it directly like you explained.
So a while back I created a SQLiteHelper Class in my Android App. I'm not 100% certain why, but the table and column names were public static final fields in a nested public static abstract class. As I recall, the goal was to protect the fields from being modified. It all works great but things are starting to get sophisticated with my app and I want to populate fields in other classes with the public static final table and column name fields. After some trial and error, and reading about abstract classes, static classes, and nesting classes, it occurred to me that can just call the field directly, as in.
String myTable = MySQLiteHelper.dbFields.TABLE_NAME_REMINDER;
Even though I've read up on these topics, how it all comes together in my specific case is still making me scratch my head. So my question is, since the fields are static final, does nesting the fields actually provide additional protection, and if the nested class is static, why also make it abstract? Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
Thanks for the help. I'm really trying to get my head wrapped around the various class implementations.
Here's the key elements of the class :
public class MySQLiteHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "Reminders.db";
private static final int DATABASE_VERSION = 5;
public int DatabaseVersion = DATABASE_VERSION;
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static abstract class dbFields implements BaseColumns {
//dbFields Table Fields
public static final String TABLE_NAME_REMINDER = "reminders";
public static final String COLUMN_REMINDER_ID = _ID;
public static final String COLUMN_REMINDER = "reminder";
public static final String COLUMN_REMINDER_ALTITUDE = "altitude";
public static final String COLUMN_REMINDER_USED = "is_used";
public static final String COLUMN_REMINDER_LASTUSED = "last_used";
public static final String COLUMN_REMINDER_ACTION = "action";
public static final String COLUMN_REMINDER_SCORE = "score";
public static final String COLUMN_REMINDER_RELATIONSHIP = "relationship";
//Special_Days Table Fields
public static final String TABLE_NAME_SPECIAL_DAYS = "special_days";
public static final String COLUMN_SPECIAL_DAYS_ID = _ID;
public static final String COLUMN_SPECIAL_DAYS_DATE = "date"; //dbDataRow strField 1
public static final String COLUMN_SPECIAL_DAYS_NAME = "name"; //dbDataRow dbData
public static final String COLUMN_SPECIAL_DAYS_ALTITUDE = "altitude"; //dbDataRow intField 1
public static final String COLUMN_SPECIAL_DAYS_USED = "is_used"; //dbDataRow Field 2
public static final String COLUMN_SPECIAL_DAYS_WARNING = "warning"; //dbDataRow intField 3
public static final String COLUMN_SPECIAL_DAYS_ACTION = "action"; //dbDataRow intField 4
}
}
since the fields are static final, does nesting the fields actually provide additional protection
No, it doesn't. As you've seen, you can access the fields even if they're nested and, since they're static and final, you can't modify them.
and if the nested class is static, why also make it abstract? Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
The purpose of abstract is to allow you to have a base class that has a method with no implementation. One classic example is an Animal class. All animals make a noise (probably not, but let's pretend) so the Animal class should have a makeNoise method. But, every animals noise is different so it doesn't make sense to have any implementation in the base class. The Cat subclass might look like public String makeNoise() { return "meow"; } and the Dog subclass might return "woof", but there's no sane implementation of makeNoise on the base class. However, if you didn't have any makeNoise on the base class you couldn't ask an arbitrary animal to makeNoise. So you'd have a public abstract String makeNoise() method on the base. That lets you call makeNoise for any animal even if all you have is a reference to an Animal.
Note that abstract has nothing to do with the class being nested or not. Other classes, nested or not, can inherit from a nested static class. It also has nothing to do with hiding data or otherwise protecting data or code.
So, to answer your question: you should make it abstract if and only if the purpose of being abstract applies here. Given your sample code, it doesn't.
since the fields are static final, does nesting the fields actually provide additional protection
Not if the nested class is public: it just provides a notational inconvenience.
and if the nested class is static, why also make it abstract?
No idea, it's your class.
Is static AND abstract required to call it directly without needing to instantiate the outer and nested classes?
No, static is sufficient.
I don't see any need for the BaseColumns interface here either. I would look seriously at using an Enum for the column names.
Say if I have a dropdown in a form and I have another nested class inside of this class .
Now what's the best way to access this dropdown from the nested class?
Unlike Java, a nested class isn't a special "inner class" so you'd need to pass a reference. Raymond Chen has an example describing the differences here : C# nested classes are like C++ nested classes, not Java inner classes.
Here is an example where the constructor of the nested class is passed the instance of the outer class for later reference.
// C#
class OuterClass
{
string s;
// ...
class InnerClass
{
OuterClass o_;
public InnerClass(OuterClass o) { o_ = o; }
public string GetOuterString() { return o_.s; }
}
void SomeFunction() {
InnerClass i = new InnerClass(this);
i.GetOuterString();
}
}
Note that the InnerClass can access the "s" of the OuterClass, I didn't modify Raymond's code (as I linked to above), so remember that the "string s;" is private because no other access permission was specified.
Nested types aren't like inner classes in Java - there's no inherent instance of the containing type. (They're more like static nested classes in Java.) They're effectively separate classes, with two distinctions:
If the containing type is generic, the nested type is effectively parameterised by the containing type, e.g. Outer<int>.Nested isn't the same as Outer<string>.Nested.
Nested types have access to private members in the containing type.
Unlike Java, in C# there is no implicit reference to an instance of the enclosing class.
You need to pass such a reference to the nested class. A typical way to do this is through the nested class's constructor.
public partial class Form1 : Form
{
private Nested m_Nested;
public Form1()
{
InitializeComponent();
m_Nested = new Nested(this);
m_Nested.Test();
}
private class Nested
{
private Form1 m_Parent;
protected Form1 Parent
{
get
{
return m_Parent;
}
}
public Nested(Form1 parent)
{
m_Parent = parent;
}
public void Test()
{
this.Parent.textBox1.Text = "Testing access to parent Form's control";
}
}
}
Static Members
Since no one has mentioned it so far: Depending on your situation, if the member variable can also be static, you could simply access it in following way.
class OuterClass
{
private static int memberVar;
class NestedClass
{
void SomeFunction() { OuterClass.memberVar = 42; }
}
}
Sidenote: I marked memberVar purposefully (and redundantly) as private to illustrate the given ability of the nested class to access private members of it's outer class.
Caution / Please consider
In some situations this might be the easiest way/workaround to get access, but ...
Static also means, that the variable will be shared across all instance objects, with all the downsides/consequences there are (thread-safety, etc.)
Static also means, that this will obviously not work if you have more than one instance of the parent's class and the variable should hold an individual value for each instance
So in most cases you might wanna go with a different approach ...
Passing a Reference
As most people have suggested (and because it is also the most correct answer), here an example of passing a reference to the outer class' instance.
class OuterClass
{
private int memberVar;
private NestedClass n;
OuterClass() { n = new NestedClass(this); }
class NestedClass
{
private OuterClass parent;
NestedClass(OuterClass p) { parent = p; }
SomeFunction() { parent.memberVar = 42; }
}
}
One other method, which is useful under certain circumstances, is to derive the nested class off of the outer class. Like so:
class Outer()
{
protected int outerVar;
class Nested() : Outer
{
//can access outerVar here, without the need for a
// reference variable (or the associated dot notation).
}
}
I have used this technique especially in the context of Structured Unit Tests. (This may not apply to the OP's particular question, but it can be helpful with nested classes in general, as in the case of this "duplicate" question: " Can i access outer class objects in inner class ")
You could pass the enclosing class as a parameter to the nested class constructor, like this:
private NestedClass _nestedClass;
public ParentClass()
{
_nestedClass = new NestedClass(this);
}
Nested classes are generally not recommended and should be private and/or internal. They are, in my opinion, useful sometimes though.
Correct me if I am wrong, you are trying to process the outer control from inner class hence you ran into this. A better way of doing this would be to handle affairs in a event driven fashion. Use an Observer pattern, Register a listener on the outer control (your nested/inner class will be the listener). Makes life simpler. I am afraid that this is not the answer you were expecting!
send the master class as an constructor parameter to the nested (inner) class.
there is a good answer above but I like to write sth.
c# nested class is by default private
private to containing class if your want to use it must be public
Right now I'm thinking about adding a private constructor to a class that only holds some String constants.
public class MyStrings {
// I want to add this:
private MyString() {}
public static final String ONE = "something";
public static final String TWO = "another";
...
}
Is there any performance or memory overhead if I add a private constructor to this class to prevent someone to instantiate it?
Do you think it's necessary at all or that private constructors for this purpose are a waste of time and code clutter?
UPDATE
I'm going for a final class with private constructor and a descriptive javadoc for the class. I can't use a ENUM (which I'd prefer) because I'm stuck on Java 1.4 for now. This would be my modification:
/**
* Only for static access, do not instantiate this class.
*/
public final class MyStrings {
private MyString() {}
public static final String ONE = "something";
public static final String TWO = "another";
...
}
Use of private constructor to prevent instantiation of class?
There are several ways you can think of users preventing from the Instantiations for the purpose of creating the Constants
As you have mentioned a class with the private Constructors and has all the string constants, is one way, even there is an overhead, that can be negligible
Else you can create a Class with Final Modifier and Define your string constants
You can use the Abstract Class with the String Constants
You can define the string constants in the properties files and can access from that, this will definitely reduce the memory and increase the flexibility of your code.
For me the best explanation is in Effective Java book: Item 4: Enforce noninstantiability with a private constructor (See more)
In Summary:
Private constructor is due utility classes were not designed to be instantiated, so is a design decision. (NO performance or memory overhead)
Making a class abstract doesn't work because can be subclassed and then instantiated.
With an abstract class the user may think the class is for inheritance.
The only way to ensure no instantiation is to add a private constructor which ensures the default constructor is not generated.
Private constructor prevents inheritance because the super constructor cannot be called (so it is not need the declare the class as final)
Throw an error in the private constructor avoids call it within the class.
Definetively, the best way would be something like next:
public class MyStrings {
private MyStrings () {
throw new AssertionError();
}
...
}
You could add a private constructor, but there are two other options.
In the same situation I would use an enumerator. If it makes sense to your implementation, you could use that instead, if it's public or private depends on where you need to use it:
public enum MyStrings {
ONE ("something"),
TWO ("something else");
private String value;
private MyStrings(String str) {
this.value = str;
}
}
Another option would be to put it in an abstract class, those can not be instantiated:
public abstract MyStrings {
public static final String STUFF = "stuff";
public static final String OTHER = "other stuff";
}
Access for both enumerator and abstract class works just like with the implementation you presented:
MyStrings.STUFF
If you don't won't anyone to make an object of the class you could make it abstract like this
public abstract class MyStrings {
public static final String ONE = "something";
public static final String TWO = "another";
}
and access your static variables like this
String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;
I think this would be a nicer solution.
I would rather use an enum to hold that Strings. This would ensure that wherever you use that Strings, you only get passed in one of the allowed Strings.
There is no performance or memory overhead if you add a private constructor in this case. As well, it is not needed since your public static variables are shared among all instances of your object.
If your class has only static members, then there is no need to have a private or public constructor. All members are accessible even without an object. In fact I find it confusing to have a constructor in such a case.
A synthetic public constructor would have been generated any way. So no.
Really a few bytes out of hundreds of millions at runtime isn't going to make much difference.
I also suggest making the class final and just for completeness have the constructor throw an exception.
If you want terse source code, you could create an enum with no values. Might cause some confusion with beginner programmers though.
That's the right way to store some constants, as also suggested in Effective Java (2nd Ed.), item 19.