Java - Class and Object 面向對象
Reference
Reference types hold reference to objects and provide a means to access those objects stored somewhere in memory. All reference types are a subclass of type java.lang.Object
.
Reference type | Brief description |
---|---|
Annotation | Provides a way to associate metadata (data about data) with program elements. |
Array | Provides a fixed-size data structure that stores data elements of the same type. |
Class | Designed to provide inheritance, polymorphism, and encapsulation. Usually models somethings in the real world and consists of a set of values that holds data and a set of methods that operates on the data. |
Enumeration | A reference for a set of objects that represents a related set of choices. |
Interface | Provides a public API and is "implemented by Java classes." |
In Java or C#, primitive variables area created in the stack while reference variable is created in heap space, which is managed by garbage collector. Memory allocation in terms of stack and heap is not specified in the C++ standard.
class
“class” is (approximately) synonymous with “type.” – on java 8 page 38
what does .class
mean in Java?
When you write
.class
after a class name, it references the class literal -java.lang.Class
object that represents information about given class.
- 因為Java所有操作都是基於對象,故如果要操作
class
必須先把class
類別實例化 - 當此類尚未實例化,使用
.class
- 當此類已經實例化,使用
.getClass()
For example, if your class is
Print.class
is an object that represents the classgetClass()
method of any (direct) instance of
- 如果您的類是
Print
,那麼Print.class
是一個Print
在運行時表示該類的對象 - 此
getClass()
與Print.class
返回的對象是同一個,並且由getClass()
獲得的對象與Print
具有同個實例化對象
Print myPrint = new Print();
System.out.println(Print.class.getName());
System.out.println(myPrint.getClass().getName());
constructor
- This guarantees that the object is properly initialized you can get your hands on it.
- Priority order:
- specific super constructor
- superclass’ constructor without parameters
- constructor by programmer in superclass
- constructor by default in superclass
modifier
static
Static is a non-access modifier in Java. Any static member can be accessed before any objects of its class are created, and without reference to any object. It is applicable for the following:
- blocks
- variables
- methods
- nested classes
Static block:
- It can be used for static initializations of a class.
- It will executed exactly only once when the class is first loaded.
- Static block
class Demo {
static int i;
static {
System.out.println("static 1");
}
Demo() {
System.out.println("static constructor");
}
static {
System.out.println("static 2, i = " + i);
}
}
public class TestDemo {
public static void main(String[] args) {
Demo con = new Demo();
System.out.println("main method");
System.out.println("Demo.i = " + Demo.i);
}
}
// static 1
// static 2, i = 0
// static constructor
// main method
// Demo.i = 0
Static variables:
- It is class-level variable instead of local variable.
- All instances of the class share the same static variable.
Static methods:
- They can only directly call other static methods.
- They can only directly access static data.
- They cannot refer to this or super in any way.
Static nested classes:
- Java allows us to define a class within another class which is called a nested class. The class which enclosed nested class is known as Outer class.
- In java, we can’t make Top level class static. Only nested classes can be static.
final
Final data:
- final primitive: final makes the value a constant
- final reference: Once the reference is initialized to an object, it can never be changed to point to another object. However, the object itself can be modified.
Blank finals:
- Blank finals are final fields without initialization values. The compiler ensures that blank finals are initialized before use.
- You’re forced to perform assignments to finals either with an expression at the point of definition of the field or in every constructor. This guarantees that the final fields is always initialized before use.
Final arguments:
- Inside the method you can read and return the argument, but you can’t change it.
i + 1;
oki++;
not allowfinal object = new Object();
not allow
Final methods
- The first reason is to put a “lock” on the method to prevent an inheriting class from changing that method meaning by overriding it. This is done for design reasons when you want to make sure that a method’s behavior is retained during inheritance.
- The second reason is that final were suggested in the past is efficiency.
Final classes
- When you say that an entire class is final (by preceding its definition with the final keyword), you’re preventing all inheritance from this class.
- The fields of a final class can be final or not, as you choose. The same rules apply to final for fields regardless of whether the class is defined as final. However, because it prevents inheritance, all methods in final class are implicitly final, since there’s no way to override them. You can include the final specifier to a method in a final class, but it doesn’t add any meaning.
- On Java 8
- See more information: final vs immutability in java-string
feature
pass by value
Java is always pass-by-value.
When an argument is passed by value, a copy of the argument’s value is passed to the called method. The called method works exclusively with the copy. Changes to the called method’s copy do not affect the original variable’s value in the caller.
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
aDog = oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
In the example above aDog.getName()
will return "Max"
. The value aDog
within main
is not changed in the function foo
with the Dog Fifi
as the
object reference is passed by value. If it were passed by reference, then the aDog.getName()
in main
would return Fifi
after the call to foo
.
Likewise:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
// but it is still the same dog:
aDog = oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
In the above example, Fifi
is the dog’s name after call to foo(aDog)
because the object’s name was set inside of foo(...)
. Any operations
that foo
performs on d
are such that, for all practical purposes, they are performed on aDog
, but it is not possible to change the value of the variable
aDog
itself.
equals and ==
equals() | == | |
---|---|---|
primary | x | value |
reference | object equals(): same as == | address comparsion |
string equals(): content comparsion |