Access Modifiers in Java Compared to C ++

I saw some discussions on StackOverflow on this subject, but I did not see anything that helped me understand the following:

I come from C ++ and lately I started to learn Java. In C ++, when protected is used, only a subclass can access a member (analogue of a field in Java).

In C ++, there are also friend classes that can access private / protected class classes that give friendship. This is a bit like the “package” field modifier in Java (the default field modifier), except that in C ++ friendship gives access to all private members, but in Java access from classes in the same package is specific to the class field.

I could not understand, believing that I want to provide access only to subclasses, this is what I can do in C ++ by declaring members protected in a class that does not "give" friendly relations.

But in Java, I don’t know how to do this, because using the “protected” field modifier - I also provide access to all classes in the package. The only way I find this is to declare a protected field and isolate the class in my package.

From this I conclude that the grouping of classes into one package should be based on the "friendship" between classes. Is this a really important consideration in grouping packages?

Another thing I don’t understand is In Java, assuming I have two fields in class A: b, c. I want to give B access to b, but not to c, and I want to give C access to c, but not b. and to Peace, I want b, c to hide. How can I do that? I assume that B, C should be in the same package as A. but by declaring b, c with the package modifier, I let B, C access both b and c. Is there a way in Java for this?

Hope for some explanation of this topic.

+5
source share
4 answers

In C ++, when protection is used, only a subclass can access a member (analogue of a field in Java).

Access specifiers also apply to member functions / methods, and not just member / field variables.

In C ++, there are also friend classes that can access private / protected class classes that give friendship. This is a bit similar to the "package" field modifier in Java (the field modifier is the default), except that in C ++ friendship gives access to all private members, but in Java access from classes in the same package is specific to the class field .

There are not only friend classes, but also functions.

It is true that the Java private-access package is similar, but it is not a complete replacement. Better to say that these two functions have a subset of the problems they solve. There are problems that can be solved with friend , but not with private-private, and vice versa.

I could not understand, assuming that I want to provide access only for subclasses, this is what I can do in C ++ by declaring members protected in a class that does not "give" friendships.

But in Java I don’t know how to do this,

Answer: you cannot.

since using the "protected" field modifier - I also provide access to all classes in the package.

That's right.

The only way I find this is to declare a protected field and the class is isolated in its package.

Technically, yes. But this creates other problems. Your class will no longer be able to access the private parts of the package of its previous package. Let's say your BaseClass was in com.example.one . You move it to com.example.two . Now he will no longer be able to access other com.example.one private package classes.

Is this really the main consideration in grouping packages?

Yes, Java is designed this way. You can try to fight the language rules , but lose the battle in any programming language.

Another thing that I don't understand in Java, assuming I have two fields in class A: b, c. I want to give B access to b, but not to, and I want to give C access to c, but not b. and to Peace I want b, c to be hidden. How can I do that?

This cannot be done in a clean way (I mean clean: without any hacks that require you to check the call stack at runtime and throw exceptions).

If this scenario bothers you because you are developing a public API, a low-tech solution that usually works fine is to create one or more *.internal and clearly document the fact that they should not be used in client code.

+2
source

These are quite a few questions together ...

But in Java, I don’t know how to do this, because using the “protected” field modifier - I also provide access to all classes in the package.

True, there is no way to grant access only to subclasses, but not to classes in a single package. It was a design decision made many centuries ago ...

The only way I find this is to declare a protected field and isolate the class in my package.

This is technically correct, although it will be of little use. Class packaging is intended to group related classes, where "related" means "classes that perform a specific relationship", i.e. They belong to the same use case, belong to the same architectural level, are in the same entity, etc.

From this I conclude that the grouping of classes into one package should be based on the "friendship" between classes. Is this a leading factor when grouping packages?

I believe that I already answered this in the previous paragraph: packaging is designed to group related classes according to some specific criteria.

For your examples of classes A, B, and C with attributes:

I assume that B, C should be in the same package as A., but by declaring b, c with the package modifier, I will let B, C access both b and k. Is there a way in Java to do this is?

The answer is no, there is no simple and clean way to do this. You could achieve this with some hacks or more advanced techniques, but, again, this was part of the decisions made by the language developers a long time ago ...

+1
source

It is implicitly assumed that all classes in the package “know” each other (because they were written by the same person / company / organization). Therefore, they either do not get access to the protected fields, or, if they do, they know how to do it correctly.

It is assumed that classes in one package are more related to each other than the parent to a derived class, because a derived class can actually be written by someone else. Therefore, they decided that confidential protection was more limited than protected.

So, I think you should not worry about how classes in one package can access each other's fields. In general, I just do not use this function, unless I write iterators.

If you have two fields, you can make them inner classes so that they have access to private fields (again, the logic is: if a class is inside another class, it knows about the semantics of this class) and can provide access to their derived classes through protected methods.

Of course, you can come up with some kind of complex token exchange protocol to make this field available only for B / C instances, but that would be a wonderful overhead, and another object can still use reflection to access all private members if you do not disable it with security policies, which is usually not the case, but again, security policies are ultimately decided by the owner of the JVM.

So, in the end, the preferred way to do what you say in Java is to either put them in the same package, or write B and C as inner classes of A so that they can directly access the private members of A and expose them their derived classes.

 public class A { public static abstract class B { protected Whatever getWhatever(A a) { return ab; } protected void setWhatever(A a, Whatever value) { ab = value; } } public static abstract class C { protected Whatever getWhatever(A a) { return ac; } protected void setWhatever(A a, Whatever value) { ac = value; } } private Whatever b; private Whatever c; } 

again, you always assume that classes in one package will never do anything wrong.

+1
source

Short answer: there is no way to do this.

If you are concerned about the intrusion from clients introducing the class into your package to gain illegal access, you can move the secret code into a separate package and make the package sealed in the bank that you deliver to: http://docs.oracle.com/javase/ tutorial / deployment / jar / sealman.html

0
source

Source: https://habr.com/ru/post/1214676/


All Articles