Class-specific method visibility - java

Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"

There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);

No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.

Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.

With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}

Related

Multiple layer inheritance - Java

If class a extends class b, and class b extends class c, does a inherit from both c and b? If so, in case of conflict between the 2, is there an error or does one override another (and if so, which one)?
Please rename the question if it is unsuitably titled.
EDIT: what I mean by conflict is something like the following:
class c {
int foo;
//Stuff
}
class b extends c {
String foo;
//Stuff
}
class a extends b {
//Stuff
}
Is a.foo a string or an int?
Another edit: So from what I gather, inheritance here is a bit like CSS - the closer the rule is set, the larger priority it has (e.g. inline styles override stylesheets). Is that a good way of considering this, or is it significantly different?
If something exists in both b and c, a will inherit whichever one b uses.
Yes, a inherits from b and c. I don't see how there can be a conflict in this situation since b's method overrides will be valid for a. You may be thinking of the diamond problem that comes from conflicts from multiple inheritance, but that's when you have two different parents, not two parents with one parent being the parent of the other.
You can run into a "soft" diamond problem with interfaces, where two methods have the same signature, but the rules for one method don't match those of another. Since neither interface has an implementation for their methods, there is no compilation problem (that I know of), just a logical problem.
Edit Ah, I've seen your edit regarding variables, and I agree with Jimpanzee's response to it. It's certainly easy to test:
public class Test3 {
public static void main(String[] args) {
MyA myA = new MyA();
System.out.println("foo := " + myA.foo);
}
}
class MyC {
public int foo = 3;
//Stuff
}
class MyB extends MyC {
public String foo = "foo";
//Stuff
}
class MyA extends MyB {
}
well, the rule is as follows.
Any subclass will inherit nearest up its hierarchy. so a will get everything from b. Because everything which is on inheritance stack will be available till b. as b had inherited already everything from its inheritance hierarchy.
Secondly, if b over-rides anything(instance variable/method), then a will see over-ridden version. So in your case a will get String foo.
This answer has a much better example, and points out that doing this sort of thing is considered bad practice. (Eclipse will give you a warning, for example.) Extending your code a bit:
class c {
int foo = 42;
//Stuff
}
class b extends c {
String foo = "foostr";
//Stuff
}
class a extends b {
//Stuff
}
class Main{
public static void main(String[] args){
a mya = new a();
System.out.println(mya.foo);
}
}
Running java Main prints foostr.
In Java only methods are subject to overriding. Everything else is just inherited and there is only the issue of a namespace clash, but everything is still accessible. In your example both foos are accessible in A (I've corrected the class names to make them conform to the strong Java naming conventions):
class C {
int foo;
//Stuff
}
class B extends C {
String foo;
//Stuff
}
class A extends B {
String x = ((B)this).foo;
int i = ((C)this).foo;
}
Yes, it inherits from both c and b.
In order to prevent/avoid conflicts, Java support a single hierarchy model (differently from other OOP languages like C++ which allow multiple-class inheritance model).

Upcasting in Java and two separate object properties

Trying to understand upcasting in Java. Recently observed strange behavior.
Example:
public class A extends B {
public int i = 2;
public void printI() {
System.out.println("print i = " + this.i);
}
public static void main(String[] args) {
B a = new A(); // <- upcasting here
System.out.println("i = " + a.i);
a.printI();
}
}
class B {
public int i = 1;
public void printI() {}
}
//Output:
//i = 1
//print i = 2
Seems, that upcasted object has two separate "i" properties. One "i" accessible directly (a.i) and the other through methods of child class (a.printI()).
Looks like upcasted object gets properties from superclass and methods from child class.
How object can have two separate "i"s?!
Seems, that upcasted object has two separate "i" properties.
Firstly, it's worth being clear about terminology. There's no such thing as an "upcasted object" - and "i" is a field in each of A and B.
But yes, there are two separate fields here. It's not like one field "overrides" another or anything like that.
It's not clear what you were trying to achieve, but the declaration of i in A shadows the declaration of i in B. See section 6.4 of the Java Language Specification for more information.
Note that in almost all cases, fields should be private - at which point the hiding really doesn't matter, as you wouldn't try to refer to a variable which wasn't declared in the class you're coding in anyway.
That's how Java works. You have both fields "available", they just happen to have the same name. When you reference from the subclass, it is hiding the superclass' version, but it is still there.

java - find out the type of class which implements of other classes

I have a kind of specific problem, let's say, that I have
public interface A {
}
//------------------------------
public class B implements A {
static int countx = 0;
}
//----------------------------------
public class C implements A {
static int county = 0;
}
//----------------------------------
public class Arc {
public A from;
public A to;
//========================================
and now I have an object a (which is an instance of Arc) and I want to find out whether it is an instance of B or C and get to the atributes countX or countY (stg like a.from.countX)
any ideas? :)
I think you could use instanceof to solve this issue
as in
if(a instanceof B) return a.countx
if(a instanceof C) return a.county
Your current design is not good from the OOP standpoint. You need some encapsulation and polymorphism. In an OOP language, you don't explicitly check for the type of an object, you arrange for that to happen automatically via dynamic dispatch. So whatever data you need from both B and C, add a method to the interface A that will get that data and then implement the method in B and C accordingly. Also, don't use public instance fields, that breaks encapuslation.
Use instanceof and a typecast:
if (a.from instanceof B) {
B b = (B)a.from;
b.countx;
}
Edit: But you should really not need such a thing! If you do, you can probably redesign it to not produce ugly code like this.
For example you could let your interface A have a method getCount() and let your classes B and C implement these, by returning countx or county.
Edit2: I just noticed that your countx and county members are static! Why would you do that? static means, that they don't "act" upon instances of your class but on your class object (they are "class members"). This means that you can access and modify these variables everywhere by accessing them through A.countx or B.county; you most probably don't want this, because multiple instances of class A will share the same countx!
If you have an object that is an instance of Arc, then how is it also an instance of B or C? I feel like your code is flawed and needs restructuring. For example, as Tudor pointed out, "There is no relation between the classes Arc and A in your hierarchy."
If you simply want to have information about the classes :
getClass().getSuperclass()
Regards,
Erwald
Think about it like this :
What makes me want to discriminate between a B and a C ? Is it an operation? If so, just implement those operations appropriately in B vs C and let dynamic dispatch take care of the rest.
interface Operation {
public Result operate(String[] args);
}
class A implements Operation {
#Override
public Result operate(String[] args) {
//I need to do some special calculations for an A...
for(String arg : args) {
}
.
.
.
}
}
class B implements Operation {
#Override
public Result operate(String[] args) {
//i know this does nothing so return the empty result
return Result.EMPTY;
}
}
Resist the tempation to use instanceof. In most cases you don't need it - and its not OO.

What is the best use of Inheritance other than reduce redundant code?

What is the best use of Inheritance, other than it will reduce redundant code!
Let us take an example
Class A:Base Class
Class B:Sub Class
and Class C.
CLASS A
^
| And CLASS C
|
|
CLASS B
i can use methods from Class A, in Class B by inheritance.
in the same i can use the methods from Class A, in Class C, by creating instance of Class A.(say A is Public)
using inheritance, only reduce creating new Object/Instance?
Plz help me to better understand!
A great benefit is polymorphism. If classes B and C both inherit from A, then whenever an object of type A is required, it can be replaced by either an object of type B or an object of type C. Assuming the corresponding methods are overriden in B and C, this is very handy to get different behavior depending on which object you pass.
Example:
class A {
public void foo() { System.out.println("A"); }
}
class B extends A {
public void foo() { System.out.println("B"); }
}
class C extends A {
public void foo() { System.out.println("C"); }
}
Then:
public static void printMessage(A obj) {
obj.foo();
}
public static void main(String[] args) {
A b = new B();
printMessage(b); // prints 'B'
A c = new C();
printMessage(c); // prints 'C'
}
The main point of inheritance is polymorphism: to allow other classes to use an instance of ClassB knowing only that it can be used as a ClassA.
My favourite example is streams - I could easily write a copyStream method taking an InputStream and an OutputStream for example, using only the methods declared on those types. Then I could copy a FileInputStream to a ByteArrayOutputStream, or use network-related streams etc, all without changing any of the code in the copyStream method.
The main reason to use inheritance is not to remove redundant code.
Inheritance and all magic made possible is a key, central point in OOP. Extending a class doesn't only allow you to use its functionality, but also modify (by polimorphism) and add more functionality.
The difference comes with the need to understand the ability to pass class B into functions that act on class A. In this sense B is-a type of A where class C has or owns A. The difference is small and only significant in certain circumstance.
That is not to say that the difference is often made explicit in code tbh. Often people will inherit when they really want ownership and sometimes they do ownership when an object really is-a type of something else.

Is "inherited" the correct term to explain static method of superclass can be accessed by subclass?

Clarification: this question is not about access modifier
Confirmed that B.m() and b.m() statements both works in the following code:
class A {
static void m() { //some code }
}
class B extends A {
}
class Example {
public static void main (String [] args) {
B.m(); // running A's m() static method
}
public void try() {
B b = new B();
b.m(); // running A's m() static method
}
}
My question is can we said "static method is inherited"?
if "inherited" is the correct term, if we add a method to B class we same signature of the static class:
class A {
static void m() { //some code }
}
class B extends A {
static void m() { //some code }
}
class Example {
public static void main (String [] args) {
B.m(); // running B's m() static method
}
public void try() {
B b = new B();
b.m(); // running B's m() static method
A a = new B();
a.m(); // running A's m() static method, no polymorphism
}
}
In this case, notice that we have no polymorphism, is it the correct term to said that "static method is inherited but not overridden, subclass static method hide superclass static method"?
Last doubt, for these 2 terms, "inherited" and "overriden", which one is directly tied to the term "polymorphism" ?
Yes, I think "inherit" is the correct term here, even if it's not as descriptive as it might be. From section 8.4.8 of the Java Language Specification:
A class C inherits from its direct superclass and direct superinterfaces all non-private methods (whether abstract or not) of the superclass and superinterfaces that are public, protected or declared with default access in the same package as C and are neither overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.
That doesn't specify instance methods, but there are specific restrictions on what is allowed to hide or override what, which wouldn't make sense if static methods were not inherited.
Really though, I would simply view static methods as "accessible without qualification" rather than anything else, given that they don't take part in polymorphism etc. I think it's worth being very clear about that - for example, one static method can hide an inherited one, but it can't override it.
In other words, while I think "inherit" is technically correct, I would try to avoid using it without any further explanation.
For your second question, I'd say that based on the above, overriding is tied to polymorphism, but inheriting isn't necessarily.
(I would also strongly advise you to avoid calling static methods "via" variables, and also to use the name of the class which declares the static method wherever you specify the name at all. I know that's not part of the question, but I thought I'd just add it anyway...)
I think trying to apply words like 'inherited' and 'overridden' to this sort of thing is not productive. It's misleading because it gives the impression there is something comparable of what goes on with virtual instance methods, and you point out there isn't.
(But as Jon Skeet points out, the Java language spec doesn't agree with me, it groups these together in the same section.)
Guys I would like to share my knowledge in java with all java lovers out there!
First of all let me tell you that static members are those members which can be accessed directly without creating an object of that particular class, when static members of a class is used in some other class then it should be used by specifying the class name .(dot) static member's name(e.g. A.i in the following example), and also if any subclass class is getting inherited from a super class which has static members and if both subclass and super class are in the same package then that static members can be accessed from the base class without even using the class name of the super class. Please go through the
Example:
package myProg;
class A
{
static int i = 10;
A()
{
System.out.println("Inside A()");
}
}
class B extends A
{
public static void main(String[] args)
{
System.out.println("i = " + i); //accessing 'i' form superclass without specifying class name
System.out.println("A.i = " + A.i); //again accessing 'i' with the class name .(dot) static member 'i'
/*
we can also use the super class' object in order to access the static member compiler
will not show any error but it is not the exact way of using static members. static members are created
so that it could be used without creating the class object. see below the usage of object to use the
static member i.
*/
A obj = new A(); //creating class A object and A() also gets called
obj.i = 20;
System.out.println("obj.i = " + obj.i);
}
}
/*
This program was to show the usage of static member. Now, lets discuss on the topic of static member inheritance.
SO GUYS I WOULD LIKE TO TELL YOU THAT STATIC MEMBERS ARE NOT INHERITED. This undermentioned program is
to show the inheritance of static members.
*/
class A
{
static int i = 10; //initially the value of i is 10
static int j = 20; //lets use one more static member int j, just to see the value of it through class A, and B
static
{
/*
This is static initialization block(SIB) of class A,
SIB gets executed first in the order of top to bottom only one time
when the class is loaded.
*/
System.out.println("A-SIB");
}
}
class B extends A
{
static
{
i = 12;//trying to modify the i's value to 12
System.out.println("B-SIB");
}
}
class D extends A
{
static int k = 15;
static
{
System.out.println("D-SIB");
}
}
class C
{
public static void main(String [] arhs)
{
System.out.println("D.k: " + D.k);
/*here we are trying to access the static member k from class D,
it will try to search this class and then that class
will be loaded first i.e. SIB of class D will be loaded and SOP
statement of class D will be printed first. When the class loading
is done then the compiler will search for the static int k in class
D and if found SOP statement will be executed with the value of k.
*/
/*
ONE GROUND RULE: as soon as the compiler see this statement the compiler will load
class D into the memory, loading of class into memory is nothing but
storing all the static members (i.e. static constant & SIBs) into the
memory.
*/
System.out.println("B.i: " + B.i);
/*Now, this is what we are talking about... we think that static int i's
value is there in class B and when we write B.i it compiles and executes
successfully BUT... there compiler is playing a major role at this statement...
Try to understand now... we know that class B is the subclass of class A
BUT when the compiler sees this statement it will first try to search
the static int i inside class B and it is not found there, then since it is
the subclass of A, the compiler will search in class A and it is found
there. NOW, WHEN STATIC INT I IS FOUND IN CLASS A THE COMPILER WILL CHANGE
THIS STATEMENT B.i TO A.i and the class B WILL NOT AT ALL BE LOADED INTO
THE MEMORY BECAUSE STATIC I IS ONLY PRESENT IN CLASS A. But in the previous
statement static int k is present inside class D so when we try to access k's value
the class D will be loaded into memory i.e. SIB will be executed and then
the SOP statement of the value of k. USING B.i IS NOT WRONG BUT COMPILER
ASSUMES THAT THE PROGRAMMER HAS MADE A MISTAKE AND IT REPLACES THE CLASS NAME
B.i TO A.i. Thus this show that static members are not inherited to the subclass.And
therefore the vaue of i will NOT BE CHANGE TO 12 AS YOU CAN SEE IN THE SIB OF
CLASS B, it will be 10 only..
*/
System.out.println("A.j: " + A.j);//this statement will be executed as it is, compiler will not make
System.out.println("A.i: " + A.i);//any modifications to these statements.
System.out.println("B.j: " + B.j);//again compiler will modify this statement from B.j to A.j
}
}
Guys if you still have any confusion mail me at this email-id:
pradeep_y2k#yahoo.co.in
Regards
Pradeep Kumar Tiwari
Ok static methods cannot be overridden but can be redefined in other words its called hiding
check this http://www.coderanch.com/how-to/java/OverridingVsHiding they explain pretty well

Categories

Resources