Chapter 14

Sharing Names among the Parts of a Java Program

In This Chapter

arrow Hiding names from other classes

arrow Exposing names to other classes

arrow Tweaking your code to find the right middle ground

Speaking of private fields and methods (and I do speak about these things in this chapter)… .

I’m eating lunch with some friends at work. “They can read your e-mail,” says one fellow. Another chimes in, “They know every single website that you visit. They know what products you buy, what you eat for dinner, what you wear, what you think. They even know your deepest, darkest secrets. Why, I wouldn’t be surprised if they know when you’re going to die.”

A third voice enters the fray. “It’s getting to the point where you can’t blow your nose without someone taking a record of it. I visited a website a few weeks ago, and the page wished me a Happy Birthday. How did they know it was me, and how did they remember that it was my birthday?”

“Yeah,” says the first guy. “I have a tag on my car that lets me sail through toll booths. It senses that I’m going through and puts the charge on my credit card automatically. So every month, I get a list from the company showing where I’ve been and when I was there. I’m amazed it doesn’t say who I was visiting and what I did when I got there.”

I think quietly to myself. I think about saying, “That’s just a bunch of baloney. Personally, I’d be flattered if my employer, the government, or some big company thought so much of me that they tracked my every move. I have enough trouble getting people’s attention when I really want it. And most agencies that keep logs of all my purchasing and viewing habits can’t even spell my name right when they send me junk mail. ‘Hello, this is a courtesy call for Larry Burg. Is Mr. Burg at home?’ Spying on people is really boring. I can just see the headline on the front page of The Times: ‘Author of Java For Dummies Wears His Undershirt Inside Out!’ Big deal!”

So I think for a few seconds, and then I say, “They’re out to get us. TV cameras! That’s the next big thing — TV cameras everywhere.”

Access Modifiers

If you’ve read this far into Java For Dummies, 6th Edition, you probably know one thing: Object-oriented programming is big on hiding details. Programmers who write one piece of code shouldn’t tinker with the details inside another programmer’s code. It’s not a matter of security and secrecy. It’s a matter of modularity. When you hide details, you keep the intricacies inside one piece of code from being twisted and broken by another piece of code. Your code comes in nice, discrete, manageable lumps. You keep complexity to a minimum. You make fewer mistakes. You save money. You help promote world peace.

Other chapters have plenty of examples of the use of private fields. When a field is declared private, it’s hidden from all outside meddling. This hiding enhances modularity, minimizes complexity, and so on.

Elsewhere in the annals of Java For Dummies, 6th Edition, are examples of things that are declared public. Just like a public celebrity, a field that’s declared public is left wide open. Plenty of people probably know what kind of toothpaste Elvis used, and any programmer can reference a public field, even a field that’s not named Elvis.

In Java, the words public and private are called access modifiers. No doubt you’ve seen fields and methods without access modifiers in their declarations. A method or field of this kind is said to have default access. Many examples in this book use default access without making a big fuss about it. That’s okay in some chapters, but not in this chapter. In this chapter, I describe the nitty-gritty details about default access.

And you can find out about yet another access modifier that isn’t used in any example before this chapter. (At least, I don’t remember using it in any earlier examples.) It’s the protected access modifier. Yes, this chapter covers some of the slimy, grimy facts about protected access.

Classes, Access, and Multipart Programs

With this topic, you can become all tangled up in terminology, so you need to get some basics out of the way. (Most of the terminology that you need comes from Chapter 10, but it’s worth reviewing at the start of this chapter.) Here’s a fake piece of Java code:

  class MyClass {
   int myField;           //a field
                       // (a member)

   void myMethod() {       //a method (another member)
  
      int myOtherField;    //a method-local variable
                       // (NOT a member)
   }
}

The comments on the right side of the code tell the whole story. Two kinds of variables exist here — fields and method-local variables. This chapter isn’t about method-local variables. It’s about methods and fields.

Believe me, carrying around the phrase “methods and fields” wherever you go isn’t easy. It’s much better to give these things one name and be done with it. That’s why both methods and fields are called members of a class.

Members versus classes

At this point, you make an important distinction. Think about Java’s public keyword. As you may already know from earlier chapters, you can put public in front of a member. For example, you can write

  public static void main(String args[]) {

or

  public amountInAccount = 50.22;

These uses of the public keyword come as no big surprise. What you may not already know is that you can put the public keyword in front of a class. For example, you can write

  public class Drawing {

   // Your code goes here

}

In Java, the public keyword has two slightly different meanings — one meaning for members and another meaning for classes. Most of this chapter deals with the meaning of public (and other such keywords) for members. The last part of this chapter (appropriately titled “Access Modifiers for Java Classes”) deals with the meaning for classes.

Access modifiers for members

Sure, this section is about members. But that doesn’t mean that you can ignore Java classes. Members or not, the Java class is still where all the action takes place. Each field is declared in a particular class, belongs to that class, and is a member of that class. The same is true of methods. Each method is declared in a particular class, belongs to that class, and is a member of that class. Can you use a certain member name in a particular place in your code? To begin answering the question, check whether that place is inside or outside of the member’s class:

  • If the member is private, only code that’s inside the member’s class can refer directly to that member’s name.

      class SomeClass {
       private int myField = 10;
    }


    class SomeOtherClass {

       public static void main(String args[]) {
          SomeClass someObject = new SomeClass();
        
          //This doesn't work:
          System.out.println(someObject.myField);
       }
    }

  • If the member is public, any code can refer directly to that member’s name.

      class SomeClass {
       public int myField = 10;
    }


    class SomeOtherClass {

       public static void main(String args[]) {
          SomeClass someObject = new SomeClass();
        
          //This works:
          System.out.println(someObject.myField);
       }
    }

Figures 14-1 through 14-3 illustrate the ideas in a slightly different way.

9781118407806-fg1401.tif

Figure 14-1: Several classes and their subclasses.

9781118407806-fg1402.tif

Figure 14-2: The range of code in which a public field or method can be used (shaded).

9781118407806-fg1403.tif

Figure 14-3: The range of code in which a private field or method can be used (shaded).

Putting a drawing on a frame

To make this business about access modifiers clear, you need an example or two. In this chapter’s first example, almost everything is public. With public access, you don’t have to worry about who can use what.

The code for this first example comes in several parts. The first part, which is in Listing 14-1, displays an ArtFrame. On the face of the ArtFrame is a Drawing. If all the right pieces are in place, running the code of Listing 14-1 displays a window like the one shown in Figure 14-4.

Listing 14-1: Displaying a Frame

  import com.burdbrain.drawings.Drawing;
import com.burdbrain.frames.ArtFrame;

class ShowFrame {

   public static void main(String args[]) {
      ArtFrame artFrame = new ArtFrame(new Drawing());

      artFrame.setSize(200, 100);
      artFrame.setVisible(true);
   }
}

9781118407806-fg1404.tif

Figure 14-4: An ArtFrame.

The code in Listing 14-1 creates a new ArtFrame instance. You may suspect that ArtFrame is a subclass of a Java frame class, and that’s certainly the case. Chapter 9 says that Java frames are, by default, invisible. So, in Listing 14-1, to make the ArtFrame instance visible, you call the setVisible method.

Now notice that Listing 14-1 starts with two import declarations. The first import declaration allows you to abbreviate the name Drawing from the com.burdbrain.drawings package. The second import declaration allows you to abbreviate the name ArtFrame from com.burdbrain.frames.

cross-reference.eps For a review of import declarations, see Chapter 4.

The detective in you may be thinking, “He must have written more code (code that I don’t see here) and put that code in packages that he named com.burdbrain.drawings and com.burdbrain.frames.” And, indeed, you are correct. To make Listing 14-1 work, I create something called a Drawing, and I’m putting all my drawings in the com.burdbrain.drawings package. I also need an ArtFrame class, and I’m putting all such classes in my com.burdbrain.frames package.

So, really, what’s a Drawing? Well, if you’re so anxious to know, look at Listing 14-2.

Listing 14-2: The Drawing Class

  package com.burdbrain.drawings;

import java.awt.Graphics;

public class Drawing {
   public int x = 40, y = 40, width = 40, height = 40;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

The code for the Drawing class is pretty slim. It contains a few int fields and a paint method. That’s all. Well, when I create my classes, I try to keep ’em lean. Anyway, here are some notes about my Drawing class:

  • At the top of the code is a package declaration. Lo and behold! I’ve made my Drawing class belong to a package — the com.burdbrain.drawings package. I didn’t pull this package name out of the air. The convention (handed down by the people who created Java) says that you start a package name by reversing the parts of your domain name, so I reversed burdbrain.com. Then, you add one or more descriptive names, separated by dots. I added the name drawings because I intend to put all my drawing goodies in this package.
  • The Drawing class is public. A public class is vulnerable to intrusion from the outside. So in general, I avoid plastering the public keyword in front of any old class. But in Listing 14-2, I have to declare my Drawing class to be public. If I don’t, classes that aren’t in the com.burdbrain.drawings package can’t use the goodies in Listing 14-2. In particular, the line

      ArtFrame artFrame = new ArtFrame(new Drawing());

    in Listing 14-1 is illegal unless the Drawing class is public.

    cross-reference.eps For more information on public and nonpublic classes, see the section entitled “Access Modifiers for Java Classes,” later in this chapter.

  • The code has a paint method. This paint method uses a standard Java trick for making things appear onscreen. The parameter g in Listing 14-2 is called a graphics buffer. To make things appear, all you do is draw on this graphics buffer, and the buffer is eventually rendered on the computer screen.

    Here’s a little more detail: In Listing 14-2, the paint method takes a g parameter. This g parameter refers to an instance of the java.awt.Graphics class. Because a Graphics instance is a buffer, the things that you put onto this buffer are eventually displayed on the screen. Like all instances of the java.awt.Graphics class, this buffer has several drawing methods — one of them being drawOval. When you call drawOval, you specify a starting position (x pixels from the left edge of the frame and y pixels from the top of the frame). You also specify an oval size by putting numbers of pixels in the width and height parameters. Calling the drawOval method puts a little round thing into the Graphics buffer. That Graphics buffer, round thing and all, is displayed onscreen.

Directory structure

The code in Listing 14-2 belongs to the com.burdbrain.drawings package. When you put a class into a package, you have to create a directory structure that mirrors the name of the package.

To house code that’s in the com.burdbrain.drawings package, you have to have three directories: a com directory, a subdirectory of com named burdbrain, and a subdirectory of burdbrain named drawings. The overall directory structure is shown in Figure 14-5.

warning.eps If you don’t have your code in the appropriate directories, you get a repulsive and disgusting NoClassDefFoundError. Believe me, this error is never fun to get. When you see this error, you don’t have any clues to help you figure out where the missing class is or where the compiler expects to find it. If you stay calm, you can figure out all this stuff on your own. If you panic, you’ll be poking around for hours. As a seasoned Java programmer, I can remember plenty of scraped knuckles that came from this heinous NoClassDefFoundError.

9781118407806-fg1405.tif

Figure 14-5: The files and directories in your project.

Making a frame

This chapter’s first three listings develop one multipart example. This section has the last of three pieces in that example. This last piece isn’t crucial for the understanding of access modifiers, which is the main topic of this chapter. So, if you want to skip past the explanation of Listing 14-3, you can do so without losing the chapter’s thread. On the other hand, if you want to know more about the Java Swing classes, read on.

Listing 14-3: The ArtFrame Class

  package com.burdbrain.frames;

import java.awt.Graphics;

import javax.swing.JFrame;

import com.burdbrain.drawings.Drawing;

public class ArtFrame extends JFrame {
   private static final long serialVersionUID = 1L;

   Drawing drawing;

   public ArtFrame(Drawing drawing) {
      this.drawing = drawing;
      setTitle("Abstract Art");
      setDefaultCloseOperation(EXIT_ON_CLOSE);
   }

   public void paint(Graphics g) {
      drawing.paint(g);
   }
}

Listing 14-3 has all the gadgetry that you need for putting a drawing on a Java frame. The code uses several names from the Java API (Application Programming Interface). I explain most of these names in Chapters 9 and 10.

The only new name in Listing 14-3 is the word paint. The paint method in Listing 14-3 defers to another paint method — the paint method belonging to a Drawing object. The ArtFrame object creates a floating window on your computer screen. What’s drawn in that floating window depends on whatever Drawing object was passed to the ArtFrame constructor.

If you trace the flow of Listings 14-1 through 14-3, you may notice something peculiar. The paint method in Listing 14-3 never seems to be called. Well, for many of Java’s window-making components, you just declare a paint method and let the method sit there quietly in the code. When the program runs, the computer calls the paint method automatically.

That’s what happens with javax.swing.JFrame objects. In Listing 14-3, the frame’s paint method is called from behind the scenes. Then, the frame’s paint method calls the Drawing object’s paint method, which in turn, draws an oval on the frame. That’s how you get the stuff you see in Figure 14-4.

Sneaking Away from the Original Code

Your preferred software vendor, Burd Brain Consulting, has sold you two files — Drawing.class and ArtFrame.class. As a customer, you can’t see the code inside the files Drawing.java and ArtFrame.java. So, you have to live with whatever happens to be inside these two files. (If only you’d purchased a copy of Java For Dummies, 6th Edition, which has the code for these files in Listings 14-2 and 14-3!) Anyway, you want to tweak the way the oval looks in Figure 14-4 so that it’s a bit wider. To do this, you create a subclass of the Drawing class — DrawingWide — and put it in Listing 14-4.

Listing 14-4: A Subclass of the Drawing Class

  import java.awt.Graphics;

import com.burdbrain.drawings.Drawing;

public class DrawingWide extends Drawing {
   int width = 100, height = 30;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

To make use of the code in Listing 14-4, you remember to change one of the lines in Listing 14-1. You change the line to

  ArtFrame artFrame = new ArtFrame(new DrawingWide());

In Listing 14-1 you can also remove the com.burdbrain.drawings.Drawing import declaration because you no longer need it.

Listing 14-4 defines a subclass of the original Drawing class. In that subclass, you override the original class’s width and height fields and the original class’s paint method. The frame that you get is shown in Figure 14-6.

9781118407806-fg1406.tif

Figure 14-6: Another art frame.

In passing, you may notice that the code in Listing 14-4 doesn’t start with a package declaration. This means that your whole collection of files comes from the following three packages:

  • The com.burdbrain.drawings package: The original Drawing class from Listing 14-2 is in this package.
  • The com.burdbrain.frames package: The ArtFrame class from Listing 14-3 is in this package.
  • An ever-present, unnamed package: In Java, when you don’t start a file with a package declaration, all the code in that file goes into one big, unnamed package. Listings 14-1 and 14-4 are in the same unnamed package. In fact, most of the listings from the first 13 chapters of this book are in Java’s unnamed package.

At this point, your project has two drawing classes — the original Drawing class and your new DrawingWide class. Similar as these classes may be, they live in two separate packages. That’s not surprising. The Drawing class, developed by your friends at Burd Brain Consulting, lives in a package whose name starts with com.burdbrain. But you developed DrawingWide on your own, so you shouldn’t put it in a com.burdbrain package.

The most sensible thing to do is to put it in one of your own packages, such as com.myhomedomain.drawings; but putting your class in the unnamed package will do for now.

One way or another, your DrawingWide subclass compiles and runs as planned. You go home, beaming with the confidence of having written useful, working code.

Default access

If you’re reading these paragraphs in order, you know that the last example ends very happily. The code in Listing 14-4 runs like a charm. Everyone, including my wonderful editor, Brian Walls, is happy.

But, wait! Do you ever wonder what life would be like if you hadn’t chosen that particular career, dated that certain someone, or read that certain For Dummies book? In this section, I roll back the clock a bit to show you what would have happened if one word had been omitted from the code in Listing 14-2.

Dealing with different versions of a program can give you vertigo, so I start this discussion by describing what you have. First, you have a Drawing class. In this class, the fields aren’t declared to be public and have the default access. The Drawing class lives in the com.burdbrain.drawings package. (See Listing 14-5.)

Listing 14-5: Fields with Default Access

  package com.burdbrain.drawings;

import java.awt.Graphics;

public class Drawing {
   int x = 40, y = 40, width = 40, height = 40;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

Next, you have a DrawingWide subclass (copied, for your convenience, in Listing 14-6). The DrawingWide class is in Java’s unnamed package.

Listing 14-6: A Failed Attempt to Create a Subclass

  import com.burdbrain.drawings.*;
import java.awt.Graphics;

public class DrawingWide extends Drawing {
   int width = 100, height = 30;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

The trouble is that the whole thing falls apart at the seams. The code in Listing 14-6 doesn’t compile. Instead, you get the following error messages:

  x is not public in com.burdbrain.drawings.Drawing;
cannot be accessed from outside package
y is not public in com.burdbrain.drawings.Drawing;
cannot be accessed from outside package

The code doesn’t compile, because a field that has default access can’t be directly referenced outside its package — not even by a subclass of the class containing the field. The same holds true for any methods that have default access.

A class’s fields and methods are called members of the class. The rules for access — default and otherwise — apply to all members of classes.

remember.eps The access rules that I describe in this chapter don’t apply to method-local variables. A method-local variable can be accessed only within its own method.

For the rundown on method-local variables, see Chapter 10.

In Java, the default access for a member of a class is package-wide access. A member declared without the word public, private, or protected in front of it is accessible in the package in which its class resides. Figures 14-7 and 14-8 illustrate the point.

warning.eps The names of packages, with all their dots and subparts, can be slightly misleading. For instance, when you write a program that responds to button clicks, you normally import classes from two separate packages. On one line, you may have import java.awt.*;. On another line, you may have import java.awt.event.*;. Importing all classes from the java.awt package doesn’t automatically import classes from the java.awt.event package.

9781118407806-fg1407.tif

Figure 14-7: Packages cut across subclass hierarchies.

9781118407806-fg1408.tif

Figure 14-8: The range of code in which a default field or method can be used (shaded).

Crawling back into the package

I love getting things in the mail. At worst, it’s junk mail that I can throw right into the trash. At best, it’s something I can use, a new toy, or something somebody sent especially for me.

Well, today is my lucky day. Somebody from Burd Brain Consulting sent a subclass of the Drawing class. It’s essentially the same as the code in Listing 14-6. The only difference is that this new DrawingWideBB class lives inside the com.burdbrain.drawings package. The code is shown in Listing 14-7. To run this code, I have to modify Listing 14-1 with the line

  ArtFrame artFrame = new ArtFrame(new DrawingWideBB());

Listing 14-7: Yes, Virginia, This Is a Subclass

  package com.burdbrain.drawings;

import java.awt.Graphics;

public class DrawingWideBB extends Drawing {
   int width = 100, height = 30;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

When you run Listing 14-7 alongside the Drawing class in Listing 14-5, everything works just fine. The reason? It’s because Drawing and DrawingWideBB are in the same package. Look back at Figure 14-8 and notice the shaded region that spans across an entire package. The code in the DrawingWideBB class has every right to use the x and y fields, which are defined with default access in the Drawing class because Drawing and DrawingWideBB are in the same package.

remember.eps To use the DrawingWideBB class in Listing 14-7, you make two changes in the original Listing 14-1. Change the first import declaration to

  import com.burdbrain.drawings.DrawingWideBB;

Also, change the ArtFrame object’s constructor call to new ArtFrame
(new DrawingWideBB()).

Protected Access

When I was first getting to know Java, I thought the word protected meant nice and secure, or something like that. “Wow, that field is protected. It must be hard to get at.” Well, this notion turned out to be wrong. In Java, a member that’s protected is less hidden, less secure, and easier to use than one that has default access. The concept is rather strange.

Think of protected access this way. You start with a field that has default access (a field without the word public, private, or protected in its declaration). That field can be accessed only inside the package in which it lives. Now add the word protected to the front of the field’s declaration. Suddenly, classes outside that field’s package have some access to the field. You can now reference the field from a subclass (of the class in which the field is declared). You can also reference the field from a sub-subclass, a sub-sub-subclass, and so on. Any descendent class will do. For an example, see Listings 14-8 and 14-9.

Listing 14-8: Protected Fields

  package com.burdbrain.drawings;

import java.awt.Graphics;

public class Drawing {
   protected int x = 40, y = 40, width = 40, height = 40;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

Listing 14-9: The Subclass from the Blue Lagoon, Part II

  import java.awt.Graphics;

import com.burdbrain.drawings.Drawing;

public class DrawingWide extends Drawing {
   int width = 100, height = 30;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

Listing 14-8 defines the Drawing class. Listing 14-9 defines DrawingWide, which is a subclass of the Drawing class.

In the Drawing class, the x, y, width, and height fields are protected. The DrawingWide class has its own width and height fields, but DrawingWide references the x and y fields that are defined in the parent Drawing class. That’s okay even though DrawingWide isn’t in the same package as its parent Drawing class. (The Drawing class is in the com.burdbrain.drawings package; the DrawingWide class is in Java’s great, unnamed package.) It’s okay because the x and y fields are protected in the Drawing class.

Compare Figures 14-8 and 14-9. Notice the extra bit of shading in Figure 14-9. A subclass can access a protected member of a class, even if that subclass belongs to some other package.

9781118407806-fg1409.tif

Figure 14-9: The range of code in which a protected field or method can be used (shaded).

tip.eps Do you work with a team of programmers? Do people from outside your team use their own team’s package names? If so, when they use your code, they may make subclasses of the classes that you’ve defined. This is where protected access comes in handy. Use protected access when you want people from outside your team to make direct references to your code’s fields or methods.

Putting non-subclasses in the same package

Those people from Burd Brain Consulting are sending you one piece of software after another. This time, they’ve sent an alternative to the ShowFrame class — the class in Listing 14-1. This new ShowFrameWideBB class displays a wider oval (how exciting!), but it does this without creating a subclass of the old Drawing class. Instead, the new ShowFrameWideBB code creates a Drawing instance and then changes the value of the instance’s width and height fields. The code is shown in Listing 14-10.

Listing 14-10: Drawing a Wider Oval

  package com.burdbrain.drawings;

import com.burdbrain.frames.ArtFrame;

class ShowFrameWideBB {

   public static void main(String args[]) {
      Drawing drawing = new Drawing();
      drawing.width = 100;
      drawing.height = 30;

      ArtFrame artFrame = new ArtFrame(drawing);
      artFrame.setSize(200, 100);
      artFrame.setVisible(true);
   }
}

So, here’s the story. This ShowFrameWideBB class in Listing 14-10 is in the same package as the Drawing class (the com.burdbrain.drawings package). But ShowFrameWideBB isn’t a subclass of the Drawing class.

Now imagine compiling ShowFrameWideBB with the Drawing class that’s shown in Listing 14-8 — the class with all those protected fields. What happens? Well, everything goes smoothly because a protected member is available in two (somewhat unrelated) places. Look again at Figure 14-9. A protected member is available to subclasses outside the package, but the member is also available to code (subclasses or not) within the member’s package.

Listing 14-10 has a main method, which is inside a class, which is in turn inside the com.burdbrain.drawings package. With most Integrated Development Environments (IDEs), you don’t think twice about running a main method that’s in a named package. But if you run programs from the command line, you may need to type a fully qualified class name. For example, to run the code in Listing 14-10, you type java com.burdbrain.drawings.ShowFrameWideBB.

technicalstuff.eps The real story about protected access is one step more complicated than the story that I describe in this section. The Java Language Specification mentions a hair-splitting point about code being responsible for an object’s implementation. When you’re first figuring out how to program in Java, don’t worry about this point. Wait until you’ve written many Java programs. Then, when you stumble upon a variable has protected access error message, you can start worrying. Better yet, skip the worrying and take a careful look at the protected access section in the Java Language Specification.

cross-reference.eps For info about the Java Language Specification, visit Chapter 3.

Access Modifiers for Java Classes

Maybe the things that you read about access modifiers for members make you a tad dizzy. After all, member access in Java is a very complicated subject with lots of plot twists and cliffhangers. Well, the dizziness is over. Compared with the saga for fields and methods, the access story for classes is rather simple.

A class can be either public or nonpublic. If you see something like

  public class Drawing

you’re looking at the declaration of a public class. But, if you see plain old

  class ShowFrame

the class that’s being declared isn’t public.

Public classes

If a class is public, you can refer to the class from anywhere in your code. Of course, some restrictions apply. You must obey all the rules in this chapter’s “Directory structure” section. You must also refer to a packaged class properly. For example, in Listing 14-1, you can write

  import com.burdbrain.drawings.Drawing;
import com.burdbrain.frames.ArtFrame;
...
ArtFrame artFrame = new ArtFrame(new Drawing());

or you can do without the import declarations and write

  com.burdbrain.frames.ArtFrame artFrame =
   new com.burdbrain.frames.ArtFrame
      (new com.burdbrain.drawings.Drawing());

One way or another, your code must acknowledge that the ArtFrame and Drawing classes are in named packages.

Nonpublic classes

If a class isn’t public, you can refer to the class only from code within the class’s package.

I tried it. First, I went back to Listing 14-2 and deleted the word public. I turned public class Drawing into plain old class Drawing, like this:

  package com.burdbrain.drawings;

import java.awt.Graphics;

class Drawing {
   public int x = 40, y = 40, width = 40, height = 40;

   public void paint(Graphics g) {
      g.drawOval(x, y, width, height);
   }
}

Then I compiled the code in Listing 14-7. Everything was peachy because Listing 14-7 contains the following lines:

  package com.burdbrain.drawings;

public class DrawingWideBB extends Drawing

Because both pieces of code are in the same com.burdbrain.drawings package, access from DrawingWideBB back to the nonpublic Drawing class was no problem at all.

But then I tried to compile the code in Listing 14-3. The code in Listing 14-3 begins with

  package com.burdbrain.frames;

That code isn’t in the com.burdbrain.drawings package. So when the computer reached the line

  Drawing drawing;

from Listing 14-3, the computer went poof! To be more precise, the computer displayed this message:

  com.burdbrain.drawings.Drawing is not public
in com.burdbrain.drawings;
cannot be accessed from outside package

Well, I guess I got what was coming to me.

technicalstuff.eps Things are never as simple as they seem. The rules that I describe in this section apply to almost every class in this book. But Java has fancy things called inner classes, and inner classes follow a different set of rules. Fortunately, a typical novice programmer has little contact with inner classes. The only inner classes in this book are in Chapter 15 (and a few inner classes disguised as enum types). So for now, you can live very happily with the rules that I describe in this section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.53.93