Announcement: Be excellent to each other.


Caravel Forum : Other Boards : Anything : Java programming paradox (I don't get it)
New Topic New Poll Post Reply
Poster Message
b0rsuk
Level: Smiter
Avatar
Rank Points: 488
Registered: 11-23-2003
IP: Logged
icon Java programming paradox (0)  
Hi.

I made a breakthrough with Java, but this puzzled me...
One of programs I'm supposed to write goes like this:

Create class ConnectionManager which manages specified number of Connection objects. (Connection class - any). Client mustn't have ability to create Connection objects directly - he should do that by a method in ConnectionManager. If class ConnectionManager runs out of Connection objects, it should return null (...)..

Easy, I thought.
Now the tricky part: we've given following example:

 //: c05:IceCream.java
// From 'Thinking in Java, 2nd ed.' by Bruce Eckel
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
// Demonstrates "private" keyword.

class Sundae {
  private Sundae() {}
  static Sundae makeASundae() { 
    return new Sundae(); 
  }
}

public class IceCream {
  public static void main(String[] args) {
    //! Sundae x = new Sundae();
    Sundae x = Sundae.makeASundae();
  }
} ///:~


And I understand the example, too. Sundae objects are created by a method in Sundae class. The constructor for Sundare is private, so it can be accessed only by something belonging toSundae class.

What makes it a paradox:
- the program I'm supposed to write should handle creating Connection objects by method in ConnectionManager.
- In example above, the constructor is private. You can't access private constructor of Connection from ConnectionManager class !

Is there some trick I don't know ? My knowledge about packages is quite vague, at the moment... It may have something to do with default package access, but neither task description nor example from TIJ says anything about packages. But task specification doesn't say anything about private access, either.
Is it possible to do without messing with packages, or packages = only way to go ?

This topic will self-destruct soon.

____________________________

http://www.gamasutra.com/features/20051128/adams_01.shtml
04-18-2005 at 07:19 PM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
stigant
Level: Smitemaster
Avatar
Rank Points: 1172
Registered: 08-19-2004
IP: Logged
icon Re: Java programming paradox (0)  
I believe (and I don't have a Java Compiler set up atm, so I can't check) but you can make an entire class internal and private to another class:

class foo{
 private class bar { ... }
 public bar CreateBar( ... ) { return new bar( ... ); }
}


So only code inside of foo can "see" class bar.

Of course, you'll need some sort of public interface to bar so that clients outside of foo can intelligently use instances of bar:

interface IBar {
 public int method1( ... );
 public int method2( ... );
}

class CFoo {
  private class CBar implements IBar {
     public bar( ... ) { ... }
     public int method1( ... ) { return 0; }
     public int method2( ... ) { return 0; }
  }

  public static IBar CreateBar( ... ) { return new CBar(...); }
}


Edit: why is my post double spaced after my first code snipit?

[Edited by stigant at Local Time:04-18-2005 at 07:52 PM]

[Edited by Mattcrampy at Local Time:04-19-2005 at 01:12 AM: Because you didn't close the code tag. There we go.]

____________________________
Progress Quest Progress
04-18-2005 at 07:50 PM
View Profile Send Private Message to User Show all user's posts Quote Reply
stigant
Level: Smitemaster
Avatar
Rank Points: 1172
Registered: 08-19-2004
IP: Logged
icon Re: Java programming paradox (0)  
Of course, private/public/protected accessors are largely only meant to help manage your code. Similarly, this pattern that you are using (commonly refered to as the factory pattern) is used to make sure that all areas of your code use the same implementation of an interface. In this case, the Connection object (I believe) is part of the standard Java SDK (its included in almost all implementations of Java), so even the code that is using the connection factory will be able to directly create a connection object. I think the point of the assignment is to create your own connection factory so that all parts of your program create connection objects in the same way, and so that if you decide to switch implementations of connection objects at a later date, all you have to do is change the connection factory and every other part of your program sees the switch.



____________________________
Progress Quest Progress
04-18-2005 at 07:57 PM
View Profile Send Private Message to User Show all user's posts Quote Reply
b0rsuk
Level: Smiter
Avatar
Rank Points: 488
Registered: 11-23-2003
IP: Logged
icon Re: Java programming paradox (0)  
It's certainly not meant to be made using internal classes - they're like two chapters away at our roadmap. (We learned about them already, but it was like 2 weaks after ConnectionManager task. I'm just lagging behind others for now.)

I think there may be an error on university's website. I guess I have to mail the teacher about that -_- . Questioning teacher may not be a very good idea sometimes, but the only alterntive I have is waiting until Wednesday. I don't want more stuff piling up.

____________________________

http://www.gamasutra.com/features/20051128/adams_01.shtml
04-18-2005 at 08:02 PM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
stigant
Level: Smitemaster
Avatar
Rank Points: 1172
Registered: 08-19-2004
IP: Logged
icon Re: Java programming paradox (0)  
Ok, then the intent of the assignment is probably convenience rather than total hiding.

In other words, the rest of your program CAN create connection objects by themselves, but they DON'T. Instead, they use the connection manager class to create connection objects for them. Enforcement of this semantic will be at the programmer level rather than at the compiler level.

____________________________
Progress Quest Progress
04-18-2005 at 08:11 PM
View Profile Send Private Message to User Show all user's posts Quote Reply
stigant
Level: Smitemaster
Avatar
Rank Points: 1172
Registered: 08-19-2004
IP: Logged
icon Re: Java programming paradox (0)  
Actually, if I may, the issue is that in the Sundae example, the method CreateSundae is a method of the Sundae class, and therefore can use the private constructor of the Sundae class.

In the connection example, the class that is making connection (the connection manager) is NOT the connection class. So either the connection constructor must be public so that connectionmanager can use it (in which case ANYBODY can use the constructor anyway), or the connection class must be an internal class for the connection manager.

I guess there's a third option:

interface IConnection {
   //connection methods here
}

//each instance of connection manager is a connection
class CConnectionManager implements IConnection {
   private CConnectionManager(...) { ... )
   public static IConnection CreateConnection( ... ) {
     return new CConnectionManager( ... );
   }
}


However, that doesn't seem as nice as the other options since an object should either be a connection or a connection manager. Not both.



____________________________
Progress Quest Progress
04-18-2005 at 08:53 PM
View Profile Send Private Message to User Show all user's posts Quote Reply
Maurog
Level: Smitemaster
Avatar
Rank Points: 1496
Registered: 09-16-2004
IP: Logged
icon Re: Java programming paradox (0)  
B0rsuk, what's happening is this:
The constructor of Sundae is private. This means you cannot do stuff like "Sundae _sun = new Sundae()".
Instead, you are supposed to use a static method of the Sundae class which gives you a new Sundae.
static Sundae makeASundae() { 
    return new Sundae(); 
}
Since the function makeASundae is static and public, you can call it anywhere, including from any other class:
~~~~Inside a function of a totally different class~~~~
Sundae x = Sundae.makeASundae();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

So in fact, you can call a makeAConnection() function of the Connection class from within the ConnectionManager. You can call it because it's public, so it can be called, and because it's static meaning you don't need an instance of Connection to run it - it's a function of the whole class, not of an object belonging to that class.

So I guess the teacher want the following to happen -
The user: _cm = new ConnectionManager ;
The user: _con = _cm.gimmeAConnection() ;
>The _cm: *Hey, he wants a new connection!*
>The _cm: Connection con = Connection.makeAConnection() ;
>The _cm: *Do some mysterious adjustments to his database and the new connection*
>The _cm: return con ; (or "return null ;" if failed some conditions)
>The user: Yay, I have a connection now!


____________________________
Slay the living! Raise the dead!
Paint the sky in crimson red!
04-18-2005 at 08:54 PM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
b0rsuk
Level: Smiter
Avatar
Rank Points: 488
Registered: 11-23-2003
IP: Logged
icon Re: Java programming paradox (0)  
Stigant:
interfaces are even more away than internal classes.

Maurog: I figured that much myself. Yes, the static method from Sundae is public, and the constructor is private. The method can access constructor because it's the same class. But...

1. it should be impossible to create a new Connection object directly
2. The only way to do that should be a method in ConnectionManager. That's not the same class. I disallow creating directly by making constructor private, but in Sundae example anyone can call the method from Sundae. That makes ConnectionManager class useless.

3* - ConnectionManager should disallow creating more than X objects.

I think the teacher simply has problems with grammar.
Technically Sundae example fulfills both requirements, but have the ConnectionManager class in first place if you don't need it ?
-----------------------------

The program is not terribly needed or urgent. I thnk I'll resort to a dirty solution like this:

- add a static variable 'resources' in ConnectionManager
- the static public method from Connection class will check the value of 'resources' in ConnectionManager.
(I feel a bit dirty about static variable, but I don't know how to make Connection methods check only 'resources' variable from the right ConnectionManager. I don't quite understand this keyword.Anyway, there's nothing in task description prohibiting static variables)

____________________________

http://www.gamasutra.com/features/20051128/adams_01.shtml
04-19-2005 at 01:05 PM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
silver
Level: Smitemaster
Rank Points: 913
Registered: 01-18-2005
IP: Logged
icon Re: Java programming paradox (+2)  
one solution to stick to the letter of the assignment might be to stick them in a seperate directory (thus package):

--- file Connection ---

package yourprogram.connectivity;
public class Connection {
    Connection() { }
}

--- file ConnectionManager ---

package yourprogram.connectivity;
public class ConnectionManager {
    public static Connection getNewConnection() {
        ... 
        return new Connection();
    }
}


in theory, only things in the package connectivity should be able to see the constructor for Connection. unless Java panics (it seems to only like package level scope on some things, a problem which could have been solved by making a keyword for declaring it instead of making it "the absence of keywords")

---

why separate them? because tomorrow you might realize that you should be returning one of three subclasses of connection based on system resources or phase of the moon or whatever. instead of having that logic all over - you have that logic encapsulated in ConnectionManager (neatly avoiding the conundrum of having to have Connection know about its subclasses to return an appropriate one to you)


____________________________
:yinyang
04-19-2005 at 02:45 PM
View Profile Send Private Message to User Show all user's posts This architect's holds Quote Reply
wmarkham
Level: Master Delver
Avatar
Rank Points: 125
Registered: 12-06-2004
IP: Logged
icon Re: Java programming paradox (0)  
stigant's initial reply is good. One other comment: In Java, other classes within the same package can access protected members of a class. So another way to do this is to make the Connection constructor protected. That would allow multiple other classes in the same package to access the constructor, but classes outside of the package will not be able to do so. I think there's also a friend declaration that you can use, but that seems kinda sketchy to me.

Wait a minute. silver already said this, but didn't mention "protected". I'm pretty sure that the constructor needs to be protected, rather than private.

[Edited by wmarkham at Local Time:04-24-2005 at 07:47 AM: actually read the post before it...]
04-24-2005 at 07:45 AM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
b0rsuk
Level: Smiter
Avatar
Rank Points: 488
Registered: 11-23-2003
IP: Logged
icon Re: Java programming paradox (0)  
I already wrote the program and it was accepted.

Basically it was supposed to work just like some of you mentioned: only a method from ConnectionManager is public, all other "things" have default "" access, which means they're accessible only for classes from the same file.

____________________________

http://www.gamasutra.com/features/20051128/adams_01.shtml
04-24-2005 at 08:57 AM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
silver
Level: Smitemaster
Rank Points: 913
Registered: 01-18-2005
IP: Logged
icon Re: Java programming paradox (+1)  
protected means "private except to my subclasses". the subclasses don't even need to be in the same package. "no keyword" is package level access - only classes in the same package (regardless of which file) may access it.

I never used private, nor protected, because I wanted package level access. If the constructor for Connection had been protected, ConnectionManager wouldn't be able to access it because it's not a subclass.

And despite b0sruk's generosity to everyone else, I was the only person who posted the correct answer, so pbth :) I mean, uh, I'm sure the other people just didn't deal with these issues as recently as I.


____________________________
:yinyang
04-25-2005 at 02:35 AM
View Profile Send Private Message to User Show all user's posts This architect's holds Quote Reply
wmarkham
Level: Master Delver
Avatar
Rank Points: 125
Registered: 12-06-2004
IP: Logged
icon Re: Java programming paradox (0)  
quote:
silver wrote:
protected means "private except to my subclasses". the subclasses don't even need to be in the same package. "no keyword" is package level access - only classes in the same package (regardless of which file) may access it.

I never used private, nor protected, because I wanted package level access. If the constructor for Connection had been protected, ConnectionManager wouldn't be able to access it because it's not a subclass.


Yeah, for some reason I really didn't understand your post the first time I read it. Or, for that matter, the second time. :) The absence of an access modifier is "default access", as b0rsuk correctly calls it. And, one point that you seem to be unaware of is that "protected" access actually does allow access from other classes in the same package, in addition to allowing access from subclasses. But default access is a better solution in this case anyway, because all we really want is the access from elsewhere in the package.
04-26-2005 at 03:50 PM
View Profile Send Private Message to User Send Email to User Show all user's posts Quote Reply
AlefBet
Level: Smitemaster
Avatar
Rank Points: 979
Registered: 07-16-2003
IP: Logged
icon Re: Java programming paradox (+1)  
quote:
silver wrote:
protected means "private except to my subclasses". the subclasses don't even need to be in the same package. "no keyword" is package level access - only classes in the same package (regardless of which file) may access it.
Actually, in Java, protected means "private, except to my subclasses and members of the same package." I will refrain from expressing what I think of this policy, because mama said "if you can't say something nice...."

[Edited by AlefBet at Local Time:04-26-2005 at 06:04 PM]

____________________________
I was charged with conspiracy to commit jay-walking, and accessory to changing lanes without signaling after the fact :blush.

++Adam H. Peterson
04-26-2005 at 06:02 PM
View Profile Send Private Message to User Send Email to User Visit Homepage Show all user's posts High Scores Quote Reply
New Topic New Poll Post Reply
Caravel Forum : Other Boards : Anything : Java programming paradox (I don't get it)
Surf To:


Forum Rules:
Can I post a new topic? No
Can I reply? No
Can I read? Yes
HTML Enabled? No
UBBC Enabled? Yes
Words Filter Enable? No

Contact Us | CaravelGames.com

Powered by: tForum tForumHacks Edition b0.98.8
Originally created by Toan Huynh (Copyright © 2000)
Enhanced by the tForumHacks team and the Caravel team.