How to Restrict Access to Nested Class Member to Enclosing Class

How to restrict access to nested class member to enclosing class?

If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.

public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}

public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}

private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}

If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.

If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:

typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });

Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class

public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}

public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}

static Journal()
{
JournalEntry.Initialize();
}

static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}

This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces

Can I restrict access to private fields between static nested classes in java?

From http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1

A private class member or constructor is accessible only within the
body of the top level class (§7.6) that encloses the declaration of
the member or constructor.

You can't restrict access to the inner classes from the outer class because members, whether public or private, of inner classes can be accessed by outer classes. And in this scenario, the main method is part of Outer, so it will be able to access the members of both Inner1 and Inner2. The closest you can get to your objective is by creating an instance of an interface inside the outer class and define member variables there. These member variables will not be accessible to the outer class. Here's an example,

private interface Example{
void doSomething();
}
private Example Inner3 = new Example(){
private int privateInner3 = 2;
public void doSomething(){
System.out.println(privateInner3);
}
}

Now in your main method, you won't be able to access Inner3.privateInner3, but you can call Inner3.doSomething().

Avoid Access to Constructor of nested Class

Update:

In the End I created another class-library and defined the constructor as internal. That way it's only accessable in this assembly.

The proposed interface solution could also have worked, but I would have had to create a separate interface for each class.

Thanks for all the quick answers!

(c#) Are nested (inner) classes the only way to restrict class access to one class?

Each class that can hold multiple instances of other classes does so with a list element (e.g. FundamentalNamingConvention stores many UnitTypes in a List). Is this a proper way of doing it?

Yes - it is fine. Most likely any ICollection, IList or IEnumerable would work. But List is fine. Do note: List does allow you to add elements as well. This is sometimes undesired.

All classes (FundamentalNamingConvention, UnitType, UnitName) are only to be accessed by the NameGenerator class. To ensure this, I could simply make all these classes be inner classes of the NameGenerator but then that file would be several hundred lines of code long.

Is there a way to have the classes stored in their separate files (e.g. UnitType.cs) but still only be accessible by the NameGenerator?

Yes, you can use a partial class to split the files. E.g.:

//file1.cs
public partial class Foo
{
//normal definition

}
//file1.cs
public partial class Foo
{
private class InnerBar
{
//private inner class definition
}
}

Visibility of nested class constructor

Usually I create an interface for the functionality you want to expose to other classes, then make the nested class private and implement that interface. This way the nested class definition can stay hidden:

public class Outer
{
private class Nested : IFace
{
public Nested(...)
{
}
//interface member implementations...
}

public IFace GetNested()
{
return new Nested();
}
}

What members of the enclosing class can a static nested class access?

In Java nested non - static classes have a hidden reference to the instance of the parent class. That's why they can access all non-static members. The nested class doesn't have such an instance. However, its scope allows it to access the parent members if the parent class passes this.

So what the second quote is saying that the access doesn't happen automatically. You pass the reference to the enclosing class and the nested static class can access it. Otherwise, it doesn't know the address of the enclosing class.

In Java nested classes, can the enclosing class access private members of inner classes?

Yes, that's fine. From the JLS, section 6.6.1:

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

You can even refer to a private member of nested type X within another nested type Y so long as they share a top-level class.

At the bytecode level, I believe this is all implemented by adding synthetic package-access methods.

Nested Class member function can't access function of enclosing class. Why?

foo() is a non-static member function of A and you are trying to call it without an instance.

The nested class B is a seperate class that only has some access privileges and doesn't have any special knowledge about existing instances of A.

If B needs access to an A you have to give it a reference to it, e.g.:

class A {
class B {
A& parent_;
public:
B(A& parent) : parent_(parent) {}
void foobar() { parent_.foo(); }
};
B b_;
public:
A() : b_(*this) {}
};


Related Topics



Leave a reply



Submit