User Tools

Site Tools


java:defining_classes_in_java

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:defining_classes_in_java [2020/09/12 01:11] – [Mutators] mithatjava:defining_classes_in_java [2020/09/14 01:38] (current) – [Our first Java class] mithat
Line 1: Line 1:
-======  Defining Classes in Java ====== +======  Defining Classes in Java ======
  
 We are going to write a simple class for implementing a counter similar to one of these:((Picture from: "Totty Clicker - Gadgets at Play.com (UK)." Play.com (UK): DVDs, Music CDs, MP3s, Video Games, Books, Electronics & Gadgets - Free Delivery. [[http://www.play.com/Gadgets/Gadgets/4-/11566684/Totty-Clicker/Product.html?ptsl=1&ob=Price&fb=0#]] (accessed January 25, 2011).  We are going to write a simple class for implementing a counter similar to one of these:((Picture from: "Totty Clicker - Gadgets at Play.com (UK)." Play.com (UK): DVDs, Music CDs, MP3s, Video Games, Books, Electronics & Gadgets - Free Delivery. [[http://www.play.com/Gadgets/Gadgets/4-/11566684/Totty-Clicker/Product.html?ptsl=1&ob=Price&fb=0#]] (accessed January 25, 2011). 
Line 28: Line 28:
 Here's a Java definition for a ''ClickerCounter'' class: Here's a Java definition for a ''ClickerCounter'' class:
  
-<file java ClickerCounter.java>+<code java>
 public class ClickerCounter { public class ClickerCounter {
          
Line 41: Line 41:
     }         }    
 } }
-</file>+</code>
  
-In Java, class definitions need to go in their own files, and the files need to be called the name of the class with the ''.java'' extension.((There are certain kinds of classes that don't need to be in their own file, but that's something we can't discuss yet.)) I have deliberately not used any comments in the definition so you can more easily see the code.+I have deliberately not used any comments in the definition so you can more easily see the code.
  
-In the above, ''count'' is an attribute/instance variable that keeps track of the state of the object. the ''click'' and ''reset'' methods implement the behavior. In actuality, this is a pretty crappy class definition for reasons we'll see later. But for now it's enough to get us started+In the above, ''count'' is an attribute/instance variable that keeps track of the state of the object. and the ''click'' and ''reset'' methods implement the behavior. 
 + 
 +In actuality, this is a pretty crappy class definition for reasons we'll see later. But for now it's enough to get us started.
  
 ==== Instantiation and use ==== ==== Instantiation and use ====
  
-The above is just a class definition. It doesn't actually make an object we can use.+The above is just a class definition. It doesn't actually make any objects you can use. The code below shows you how to make, or **instantiate** a ''ClickerCounter'' object and then call the object's methods to change the state of the object
  
-The program below shows you how to make, or **instantiate** ''ClickerCounter'' and then call the object's methods to change the state of the object.+<code java> 
 +var myCounter = new ClickerCounter();  // instantiate a ClickerCounter
  
-<file java ClickerExample.java> +myCounter.reset();  // count is 0 
-public class ClickerExample {+myCounter.click();  // count is 1 
 +System.out.println(myCounter.count); 
 +myCounter.click();  // count is 2 
 +myCounter.click();  // count is 3 
 +System.out.println(myCounter.count); 
 +myCounter.reset();  // count is 0 
 +System.out.println(myCounter.count); 
 +</code>
  
 +===== Where does the code go? =====
 +
 +==== The easy-for-beginners way ====
 +If there's only one custom class in your program, an easy way to write your program is to incorporate the class definition and the program's ''main()'' method into the same class definition.
 +
 +<file java ClickerCounter.java>
 +public class ClickerCounter {
 +
 +    // Class definition (instance members)
 +    int count;
 +    
 +    void click(){
 +        count++;
 +    }
 +    
 +    void reset(){
 +        count = 0;
 +    }   
 +
 +    // Program's main method that uses the class
     public static void main(String[] args) {     public static void main(String[] args) {
         var myCounter = new ClickerCounter();  // instantiate a ClickerCounter         var myCounter = new ClickerCounter();  // instantiate a ClickerCounter
Line 71: Line 101:
 </file> </file>
  
 +This isn't generally recommended though because very often you will write more than one custom class in your program. If this is the case, the approach above won't work because Java's rules say any file can only contain at most one public class definition.((You //can// have additional non-public class definitions in a file, but that's something we can't discuss yet.))
  
-===== Access specifiers ===== +==== The better way ====
-The ''ClickerCounter'' class definition above effectively encapsulates the state and behavior of a clicker counter. But it has issues. For example, if we change our example as follows:+
  
-<file java ClickerExample.java> +A better way to manage your programs' custom classes is to put each custom class into its own file. When you do this, the files need to be the name of the class with the ''.java'' extension.
-public class ClickerExample {+
  
-    public static void main(String[] args) { +The following is how to break up the class definition and the "main" stuffHere is the file that has only the class definition:
-        var myCounter = new ClickerCounter(); +
-         +
-        myCounter.reset(); +
-        myCounter.count = 492341;  // <- LOOK HERE! +
-        System.out.println(myCounter.count); +
-        myCounter.click(); +
-        myCounter.click(); +
-        System.out.println(myCounter.count); +
-    }     +
-+
-</file>+
  
-the object will happily oblige the user's wish to set the count to some arbitrary valueThat's not something you can typically do with a clicker counter. In other words, the object offers no **protection** of its state. This is easy enough to solve with Java's access modifiers. Let's look at a modified version of our class definition that gives us some protection using access modifiers:+<file java ClickerCounter.java> 
 +public class Counter {
  
-<file java ClickerCounter.java> +    // Class definition 
-public class ClickerCounter {+    int count;
          
-    private int count; +    void click(){
-     +
-    public void click(){+
         count++;         count++;
     }     }
          
-    public void reset(){+    void reset(){
         count = 0;         count = 0;
-    }    +    }
 } }
 </file> </file>
  
-Access modifiers are placed before the start of a member. Java offers four levels of protection, and they just so happen to all start with the letter 'p': +And here is the file that has the "main" stuff:
-  * ''package'': this is what you get by default (i.e., when you don't specify anything, as in our first definition of the class). It means anything within the same package as the class definition is able to access the member. +
-  * ''public'': anyone anywhere can access the member. This is a good choice for methods that are part of the class' interface. +
-  * ''private''only those of the same class can access the member.  +
-  * ''protected'': only those of the same _or a derived_ class can access the member. ((The difference between ''private'' and ''protected'' won't be clear until you've studied class inheritance.))+
  
-With the changes made above, if we try to run ''ClickerExample'' we will see that the code will refuse to compileWhen the compiler hits the statement+<file java ClickerExample.java> 
 +public class ClickerExample {
  
-<code java> +    public static void main(String[] args) { 
-myCounter.count 492341; +        var myCounter = new ClickerCounter() /instantiate a ClickerCounter 
-</code> +         
- +        myCounter.reset();  // count is 0 
-it cannot access the ''count'' member of ''myCounter'' because we said it's privateRemember, we want our objects to be **self-governing**, and this helps make sure this is the case. +        myCounter.click();  // count is 1 
- +        System.out.println(myCounter.count); 
-<WRAP center round tip 80%> +        myCounter.click() // count is 2 
-In Java programming, it's considered a best practice to make all member variables ''private'' or ''protected'', except in some rare situations. +        myCounter.click();  // count is 3 
- +        System.out.println(myCounter.count)
-Methods can be at whatever access level is appropriate for their use. If it is part of the class' interface, it should be ''public''. If it's for use only internally by the object, it will typically be ''private'' or ''protected''+        myCounter.reset();  // count is 0 
-</WRAP> +        System.out.println(myCounter.count);
- +
- +
-===== Accessors and mutators ===== +
- +
-==== Accessors ==== +
- +
-If we comment out the offending line above, we will see that the program //still// does not compile. The reason for this is in the statement: +
- +
-<code java> +
-System.out.println(myCounter.count); +
-</code> +
- +
-The compiler is trying to access ''myCounter'''s ''count'' member, but we said that it's private so no one would clobber itBut now we can't access the value at all! +
- +
-So, once you make a member variable private or protected, how do we get its value?? The answer is you can write a public method that simply returns the value of the member variable: +
- +
-<file java ClickerCounter.java> +
-public class ClickerCounter { +
-     +
-    private int count; +
-     +
-    // NEW! accessor method +
-    public int getCount(){ +
-        return count; +
-    } +
-     +
-    public void click(){ +
-        count+++
-    } +
-     +
-    public void reset(){ +
-        count = 0;+
     }         }    
 } }
 </file> </file>
  
-This is an example of an **accessor**: a member method that provides read-only access to a value in your object's state. Accessor names typically consist of "get" followed by name of the state value (i.e.member variable) it is modifying. +This is the best way to manage your files, and the way will use in the remainder of these tutorials. However, depending on how you are expected to submit homework, you may be required to use the "easy for beginnersway to write you code.
- +
-We can now change our ''main'' method as follows: +
- +
-<code java> +
-public static void main(String[] args) { +
-    var myCounter = new ClickerCounter(); +
-     +
-    myCounter.reset();  // count is 0 +
-    System.out.println(myCounter.getCount()); +
-    myCounter.click(); +
-    myCounter.click(); +
-    System.out.println(myCounter.getCount()); +
-+
-</code> +
- +
-and life if good. Accessors are sometimes called **getters**, but I personally try to avoid that term. +
-==== Mutators ==== +
- +
-Let's now add a feature to our counter that lets the user set the maximum count: after the counter reaches the maximum, it should reset. Just like a physical clicker counter that only counts up to, say, 10,000.  +
- +
-We'll need another member variable to store this upper bound, and we'll have to modify the ''click()'' method to check it.  +
- +
-<code java> +
- +
-private int maxCount; // new member variable +
- +
-... +
- +
-// modified click() method +
-public void click(){ +
-    if (count < maxCount) { +
-        count++; +
-    } else { +
-        count = 0; +
-    } +
-+
-</code> +
- +
-Following best-practices, made ''maxCount'' private. But now how do we set it? The answer is we write a public method that sets the value. Even better, the public method can check to make sure the value it's being set to is value. Such a method is called a **mutator**: an instance method that mutate the value of a state value. Mutator names typically consist of "set" followed by with the name of the state value (member variable) being modified. +
- +
-<code java> +
-// NEW! mutator for maxCount +
-public void setMaxCount(int newMax) { +
-    if (newMax > 0) { +
-        maxCount = newMax; +
-    } else { +
-        System.out.println("Invalid new maximum count: " + newMax); +
-    } +
-+
-</code> +
- +
-Mutators should checks that new values are valid. This is another example of what's needed to make an object **self-governing**. +
- +
-Mutators are sometimes called **setters**, but I personally try to avoid that term.  +
- +
-Putting it all together, we now have: +
- +
-<file java ClickerCounter> +
-/** +
- * Encapsulate a tally counter/clicker-counter +
- */ +
-public class ClickerCounter { +
- +
-    // Member variables +
-    private int count; +
-    private int maxCount; +
- +
-    // Accessors and mutators +
-    public int getCount() { +
-        return count; +
-    } +
- +
-    public void setMaxCount(int newMax) { +
-        if (newMax > 0) { +
-            maxCount = newMax; +
-        } else { +
-            System.out.println("Invalid maximum count: " + newMax); +
-        } +
-    } +
- +
-    // Interface methods +
-    public void click() { +
-        if (count < maxCount) { +
-            count++; +
-        } else { +
-            count = 0; +
-        } +
-    } +
- +
-    public void reset() { +
-        count = 0; +
-    } +
-+
-</file> +
- +
-<WRAP center round tip 80%> +
-Many new programmers feel the need to write both accessors and mutators for all instance variables. Don't. To reduce the potential for introducing bugs, you should only write methods that will actually be used. If you don't need a accessor or mutator, don't write it. +
-</WRAP> +
- +
-===== this ===== +
- +
-sajdlfjalsdf +
- +
- +
-===== Constructors ===== +
- +
-==== Default constructors ==== +
-Instance variables have default values. For numbers, the default value is 0, for Booleans it is false, and for object references it is null. However, there will be times when you want to override these default values. For example, let's say we are counting votes for a fraudulent election and want to start our counter at 10,000 without anyone being the wiser. To do this, we will need to use a **constructor**: a member method that runs automatically whenever you instantiate the object. +
- +
-Adding a constructor to our class definition that does the nefarious deed mentioned above looks like: +
- +
-... +
- +
-Note the syntax: A constructor does not have a return type, is declared with ''public'' access, and has the same name as the class. +
- +
-So, in short, constructors are used to _initialize_ objects. They can be used for other purposes as well, but object initialization is the main reason they were invented. +
- +
-==== Parameterized constructors ==== +
- +
-===== Miscellany ===== +
- +
-==== toString() ==== +
- +
-One thing you'll want to get into the habit of doing with your class definitions is to write a ''toString()'' method. The method should return a string representation of the object. What you want that representation is up to you. The ''toString()'' method will automatically be invoked whenever Java needs a string representation of your object. An example of one for the ''ClickerCounter'' class might look like: +
- +
-<code java> +
-public String toString() { +
-    return "count: " + count; +
-+
-</code> +
- +
-Now if we want to output the state of a counter using ''System,out.println()'', we could simply write+
- +
-<code java> +
-System.out.println(myCounter); +
-</code> +
- +
-Writing a ''toString()'' instance method is especially important when your class is more complicated than the simple class we've been using here. To understand the magic by which this works, you need to have an understanding of inheritance in Java. But that shouldn't stop you from starting to do this now. +
- +
------------------------------------------------------------------------ +
  
-Copyright © 2011-2018 Mithat Konar. All rights reserved.+Copyright © 2020 Mithat Konar. All rights reserved.
java/defining_classes_in_java.1599873116.txt.gz · Last modified: 2020/09/12 01:11 by mithat

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki