In addition to public member methods, a class definition has private fields
: variables that member methods can access but class users cannot. The private access modifier precedes each private field declaration.
class user은 private field를 볼 수 없다. 외부에서 함부로 접근하지 못하도록 setter, getter을 설정하는 것이고 !
A programmer defining a class first names the class, declares private fields, and defines public member methods. A class' fields and methods are collectively called class members.
The programmer defines the details of each member method, sometimes called the class' implementation. A method definition provides an access modifier, return type, name, parameters, and the method's statements. A member method can access all private fields.
The RunnerInfo class below maintains information about a person who runs, allowing a class user to set the time run and the distance run, and to get the runner's speed. The subsequent question set asks for the missing parts to be completed.
A class' public methods
are commonly classified as either mutators or accessors.
mutator
method may modify ("mutate") a class' fields.accessor
method accesses fields but may not modify a class' fields.Commonly, a field has two associated methods: a mutator
for setting the value, and an accessor
for getting the value, known as a setter
and getter
method, respectively, and typically with names starting with set or get. Other mutators and accessors may exist that aren't associated with just one field, such as the print() method below
A programmer commonly creates private methods, known as private helper methods
, to help public methods carry out tasks.
A good practice is to initialize all variables when declared. This section deals with initializing the fields of a class when a variable of the class type is allocated.
A programmer can initialize fields in the field declaration. Any object created of that class type will initially have those values.
Java provides a special class member method, known as a constructor
, that is called when an object of that class type is created, and which can be used to initialize all fields. The constructor has the same name as the class. The constructor method has no return type, not even void. Ex: public Restaurant() {...} defines a constructor for the Restaurant class.
A programmer specifies the constructor that should be called when creating an object. Ex: Restaurant favLunchPlace = new Restaurant(); creates a new Restaurant object and calls the constructor Restaurant().
If a class does not have a programmer-defined constructor, then the Java compiler implicitly defines a default constructor with no arguments. The Java compiler also initializes all fields to their default values.
A reference
is a variable type that refers to an object. A reference may be thought of as storing the memory address of an object. Variables of a class data type (and array types, discussed elsewhere) are reference variables.
포인터 역할과 비슷한 것으로 추정
A statement like TimeHrMin travelTime;
The reference variables do not store data for those class types. Instead, the programmer must assign each reference to an object, which can be created using the new operator.
The statement TimeHrMin travelTime;
reference variable
with an unknown value.The new operator allocates memory for an object, then returns a reference to the object's location in memory.
Thus, travelTime = new TimeHrMin();
Java does not provide a direct way to determine the memory location of an object, or to determine the exact address to which a reference variable refers. The "value" of a reference variable is unknown to the programmer.
This material's animations show the memory address of an object as the value for a reference variable for illustrative purposes, to illustrate that a reference variable and its object are separate entities in memory.
Two or more reference variables may refer to the same object, as illustrated below.
lastRun = currRun을 통해 같은 object를 가리키게 된 상황
An object's member method is called using the syntax objectReference.method()
. The object reference before the method name is known as an implicit parameter of the member method because the compiler converts the call syntax objectReference.method(...) into a method call with the object reference implicitly passed as a parameter. Ex: method(objectReference, ...).
Within a member method, the implicitly-passed object reference is accessible via the keyword this. In particular, a class member can be accessed as this.classMember. The "."
is the member access operator.
Using this makes clear that a class member is being accessed and is essential if a field member and parameter have the same identifier. In the example below, this is necessary to differentiate between the field member sideLength and the parameter sideLength.
The animation below illustrates how member methods work. When an object's member method is called, the object's reference, which can be thought of as the object's memory address, is passed to the method via the implicit "this" parameter. An access in setTime() to this.hours first goes to the object's address, then to the hours field.
The "this" keyword
can also be used in a constructor to invoke a different (overloaded) constructor. In the default constructor below, this(0, 0); invokes the other constructor to initialize both fields to zero. For this example, a programmer could have just set both fields to zero within the default constructor. However, invoking other constructors is useful when a class' initialization routine is lengthy and avoids rewriting the same code.
Java variables are one of two types.
primitive type
variable directly stores the data for that variable type, such as int, double, or char. Ex: int numStudents = 20; declares an int that directly stores the data 20.reference type
variable can refer to an instance of a class, also known as an object.Java provides several wrapper classes that are built-in reference types that augment the primitive types. The Integer data type is a built-in class in Java that augments the int primitive type. Ex: Integer maxPlayers = 10; declares an Integer reference variable named maxPlayers that refers to an instance of the Integer class, also known as an Integer object. That Integer object stores the integer value 10.
Many of Java's built-in classes, such as Java's Collection library, only work with objects. For example, a programmer can create an ArrayList containing Integer elements, e.g., ArrayList frameScores; but not an ArrayList of int elements. Wrapper classes allow the program to create objects that store a single primitive type value, such as an integer or floating-point value. The wrapper classes also provide methods for converting between primitive types (e.g., int to double), between number systems (e.g., decimal to binary), and between a primitive type and a String representation.
A programmer may use a wrapper class variable in expressions in the same manner as the primitive type int. An expression may even combine Integers, ints, and integer literals.
A wrapper class object (as well as a String object)
is immutable, meaning a programmer cannot change the object via methods or variable assignments after object creation.
When the result of an expression is assigned to an Integer reference variable, memory for a new Integer object with the computed value is allocated, and the reference (or address) of this new object is assigned to the reference variable. A new memory allocation occurs every time a new value is assigned to an Integer variable, and the previous memory location to which the variable referred, remains unmodified.
The following example uses the Double class to calculate the amount of time necessary to drive or fly a certain distance.
When using a literal for initialization, the programmer must ensure that the literal's value falls within the appropriate numeric range, e.g., -2,147,483,648 to 2,147,483,647 for an integer. The wrapper classes (except for Character and Boolean) declare the MAX_VALUE and MIN_VALUE fields, which are static fields initialized with the maximum and minimum values a type may represent, respectively. A programmer may access these fields to check the supported numeric range by typing the wrapper class' name followed by a dot and the field name, as in Integer.MIN_VALUE, which returns -2,147,483,648.
For reference variables of wrapper classes (e.g., Integer, Double, Boolean), a common error is to use the equality operators == and != when comparing values, which does not work as expected. Using the equality operators on any two reference variables evaluates to either true or false depending on each operand's referenced object. For example, given two Integers num1 and num2, the expression num1 == num2 compares if both num1 and num2 reference the same Integer object, but does not compare the Integers' contents. Because those references will (usually) be different, num1 == num2 will evaluate to false. This is not a syntax error, but clearly a logic error.
Although a programmer should never compare two reference variables of wrapper classes using the equality operators, a programmer may use the equality operators when comparing a wrapper class object with a primitive variable or a literal constant. The relational operators <, <=, >, and >= may be used to compare wrapper class objects. However, note that relational operators are not typically valid for other reference types. The following table summarizes allowable comparisons.
Reference variables of wrapper classes can also be compared using the equals()
and compareTo()
methods. These method descriptions are presented for the Integer class, but apply equally well to the other wrapper classes. Although the use of comparison methods is slightly cumbersome in comparison to relational operators, these comparison methods may be preferred by programmers who do not wish to memorize exactly which comparison operators work as expected.
The keyword static
indicates a variable is allocated in memory only once during a program's execution. Static variables reside in the program's static memory region and have a global scope. Thus, static variables can be accessed from anywhere in a program.
In a class, a static field is a field of the class instead of a field of each class object. Thus, static fields are independent of any class object, and can be accessed without creating a class object. Static fields are declared and initialized in the class definition. Within a class method, a static field is accessed using the field name. A public static field can be accessed outside the class using dot notation: ClassName.fieldName.
Static fields
are also called class variables, and non-static fields are also called instance variables.
public static nextInt가 정의되어 있기 때문에 따로 입력받지 않음
A static member method
is a class method that is independent of class objects. Static member methods are typically used to access and mutate private static fields from outside the class. Since static methods are independent of class objects, the this parameter is not passed to a static member method. So, a static member method can only access a class' static fields.
class object와는 무관하기 때문에 this로 호출할 수가 없음
Commonly, one class is similar to another class but with some additions or variations. Ex: A store inventory system might use a class called GenericItem that has itemName and itemQuantity data members. But for produce (fruits and vegetables), a ProduceItem class with data members itemName, itemQuantity, and expirationDate may be desired.
independent class 와 derived class에 대하여
Various inheritance variations are possible:
A derived class
can serve as a base class for another class. Ex: class FruitItem extends ProduceItem {...} creates a derived class FruitItem from ProduceItem, which was derived from GenericItem.
The example below defines a Business class with private fields name and address. The Restaurant class is derived from Business and adds a rating private field with a getter and setter.
The members of a derived class
have access to the public members of the base class, but not to the private members of the base class. This is logical—allowing access to all private members of a class merely by creating a derived class would circumvent the idea of private members. Thus, adding the following member method to the Restaurant class yields a compiler error.
public이 아니라 private면 derived되더라도 접근 불가
Recall that members of a class may have their access specified as public or private. A third access specifier is protected
, which provides access to derived classes and all classes in the same package but not by anyone else. Packages are discussed in detail elsewhere, but for our purposes a package can just be thought of as the directory in which program files are located. Thus, classes in the same package are located in the same directory. The following illustrates the implications of the protected access specifier.
In the following example, the member called name is specified as protected and is accessible anywhere in the derived class. Note that the name member is also accessible in main()—the protected specifier also allows access to classes in the same package; protected members are private to everyone else.
To make Restaurant's displayRestaurant() method work, we merely need to change the private members to protected members in class Business. Business's class members name and address thus become accessible to a derived class like Restaurant. A programmer may often want to make some members protected in a base class to allow access by derived classes, while making other members private to the base class.
The following table summarizes access specifiers.
Separately, the keyword "public"
in a class definition like public class DerivedClass {...} specifies a class's visibility in other classes in the program:
Most beginning programmers define classes as public when learning to program.
When a derived class defines a member method that has the same name and parameters as a base class's method, the member method is said to override
the base class's method. The example below shows how the Restaurant's getDescription() method overrides the Business's getDescription() method.
The @Override annotation
is placed above a method that overrides a base class method so the compiler verifies that an identical base class method exists. An annotation is an optional command beginning with the "@" symbol that can provide the compiler with information that helps the compiler detect errors better. The @Override annotation causes the compiler to produce an error when a programmer mistakenly specifies parameters that are different from the parameters of the method that should be overridden or misnames the overriding method. Good practice is to always include an @Override annotation with a method that is meant to override a base class method.
Overriding differs from overloading. In overloading
, methods with the same name must have different parameter types, number of parameters, or return values. In overriding
, a derived class member method must have the same parameter types, number of parameters, and return value as the base class member method with the same name.
Overloading
is performed if derived and base member methods have different parameter types; the member method of the derived class does not hide the member method of the base class.
An overriding method
can call the overridden method by using the super keyword. Ex: super.getDescription(). The super keyword
is a reference variable used to call the parent class's methods or constructors.
A common error is to leave off super when wanting to call a base class method. Without the use of the super keyword, the call to getDescription() refers to itself (a recursive call), so getDescription() would call itself, which would call itself, etc., never actually printing anything.
(super을 붙이지 않으면 무한로프를 돈다는 말이지)