Java類的定義
人以類聚,物以群分,Java 類把某些具體的相似的實體,總結抽象出描述這些具體實體的屬性,和行為。比如人類,從很多的具體的人,老人,小孩等等總結,抽象出來的。當你給火星人談“人類”的時候,他可能一臉懵逼,但你說人類的代表就像你這樣的,他可能就秒懂了,這說明類是抽象的。只有具體到實例,才能具體的了解類。
Java面向對象的三大特征: 封裝、繼承、多態。
-
定義格式
class 類名{ 聲明成員變量; 聲明成員方法; }
-
命名規范
1、第一個字母要大寫;
2、“見名知意”,名字有一定的意義,Student、Person、Car
3、名字中具有一定功能性的描述,如OrderService,StudentManager
類定義案例
public class Demo{
public static void main(String[] args) {
People people = new People();
people.name = "樓主";
people.eat();//樓主正在吃
}
}
//這也說明一個.java文件能有多個類
class People {
String name;
public void eat() {
System.out.println(this.name + "正在吃");
}
}
圖解

局部變量與成員變量的區別
局部變量: 隨著方法入棧初始化,隨著方法出棧而消失
成員變量: 隨著對象的初始化創建,隨著對象的回收而消失
案例
public class Demo {
public static void main(String[] args) {
Student student = new Student();
student.name = "萌萌";
student.age = 18;
student.say();//1今年萌萌18歲
student = null;//person指向的堆內存會被垃圾回收器(GC)回收
}
}
class Student {
String name;
int age;
public void say() {
int id = 1;
System.out.println(id + "今年" + name + age+"歲");
}
}
java 訪問權限
-
成員的四個訪問權限
private 私有的,只能在類的內部訪問
[default] 默認的,可以在同一個包下訪問
protected 受保護的,可以在類的內部和子類中訪問
public 公有的,可以在任一地方訪問
-
this 關鍵字
this: 指向當前類對象,當出現局部變量與成員變量重命名時,需要使用this來訪問成員變量。
案例
public class Demo {
public static void main(String[] args) {
Person person=new Person(); //調用了默認的構造方法(無參的)
//stu.name="張三"; //私有的成員是不能通過對象訪問
person.setName("張三");
person.setAge(30);
person.sex="女";
System.out.println("Person: "+person.toString());//Person: [name=張三,age=30,sex=女]
}
}
class Person { //數據實體類
private String name; //默認值為null
private int age; //默認值為0
String sex = "男";
//方法名的命名方式為駝峰命名方法(setXxx,getXxx)
public void setName(String name) {
this.name = name; //this.name代表的是成員變量
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
//實現將對象轉成字符串的方法
public String toString() {
return "[name=" + name + ",age=" + age + ",sex=" + sex + "]";
}
}
如圖
| 修飾符 | 當前類 | 同包 | 子類 | 其他包 |
| ------------- |:-------------:|: -----:|:-----------:|-------:|
| public | 可以 | 可以 | 可以 | 可以 |
| protected | 可以 | 可以 | 可以 | 不可以 |
| 默認(friendly) | 可以 | 可以 | 不可以 | 不可以 |
| private | 可以 | 不可以 |不可以 | 不可以 |
類的構造方法
構造方法的作用,初始化成員變量,也是了解一個類的入口。
-
定義格式
public 類名(){}且無返回值
-
注意的點
1、構造方法只能用于初始化對象,不能被對象調用和類的成員方法中調用
2、 默認構造方法為無參的,也是隱式構造方法(無需提供)
3、 可以提供有參的構造方法,但會覆蓋默認的構造方法 在初始化時,必須顯示使用構造方法
4、 兩個構造方法之間可以相互調用,使用this()方式調用,但必須在第一行。
構造函數案例
public class Demo{
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.say();
Teacher xiao = new Teacher("小小");
xiao.say();
//匿名對象:不存在一個引用指向這個對象
new Teacher("shabi").say(); //當執行完成后,對象空間可以被垃圾回收器回收
}
}
class Teacher { //動物類
private String name;
public Teacher() { //無參的構造方法
this("teacher"); //調用有參的構造方法,必須在第一行
//name="teacher";
}
public Teacher(String name) { //帶有參數的構造方法,默認情況下會覆蓋無參的構造方法
this.name = name;
}
public void say() {
System.out.println("大家好,Teacher,我叫 " + name);
}
}
static 關鍵字
-
static 修飾的成員是靜態成員變量。它有以下特點:
1、 隨著類的加載,會在方法區的靜態區中開辟內存空間,初始化數據
2、 可以通過類名直接訪問,格式:類名.靜態成員變量
3、 一般用于存儲所有類的共享數據
-
靜態成員方法,特點:
1、靜態方法中只能訪問靜態成員(不能使用this引用)
2、非靜態方法中可以訪問靜態成員(都能訪問)
-
靜態成員變量與非靜態成員變量的區別
1、 生命周期
靜態成員變量隨著類的加載,在方法區的靜態區中初始化,在程序結束時而消失;成員變量是隨著對象的初始化,在堆中創建與初始化,在對象被垃圾回收時而消失。
2、存儲的特點
靜態成員變量是所有對象共享存儲的數據;成員變量是某一對象存儲的數據。
3、訪問方式
靜態成員變量可以通過類名直接訪問,也可以對象訪問;成員變量只能通過對象來訪問。
static案例
public class Demo {
public static void main(String[] args) {
Student1.sex="男"; //直接通過類名來訪問類中的靜態成員變量
Student1 s1= new Student1();
s1.setAge(30);
s1.say();//hello,女,30
s1.sex="不男不女"; //也可以通過類的對象訪問類中的靜態成員變量
s1.say();//hello,女,30
Student1 s2=new Student1();
s2.setAge(25);
s2.say();//hello,女,25
}
}
class Student1{
static String sex="男"; //靜態成員變量
private int age;
public void setAge(int age){
this.age=age;
}
public static void setSex(String sex){//靜態成員方法
Student1.sex=sex;//將方法中的局部變量的值 賦給靜態成員變量
//age=30; //在靜態方法中不能訪問非靜態成員
}
public void say(){ //在成員方法中,是否可以訪問靜態成員變量
setSex("女"); //在非靜態方法中可以訪問靜態方法
System.out.println("hello,"+sex+","+age);
}
}
靜態代碼塊,構造代碼塊
靜態代碼塊
static{ }
主要作用:初始化靜態成員變量,隨著類的加載而執行的,只執行一次。
構造代碼塊
{ code...}
優先于構造方法執行,主要是來初始化成員變量,隨著對象的創建而執行,每次創建對象都會執行。
static修飾符什么時候使用?
1、 在多個類之間共享成員變量時,需要將其改為static靜態成員變量
2、 如果一個成員方法中沒有訪問本類的成員變量,則將其改為static靜態成員方法
注:在程序優化中,建議不要過多地使用static,因為它會長時間地保留在內存中(方法區的靜態區)
有靜態代碼塊,構造代碼塊時,對象的初始化過程
1、加載類的字節碼文件到jvm的方法區中
2、為靜態成員變量在靜態區開辟內存空間,并初始化默認值
3、加載靜態代碼塊,初始化靜態成員變量
4、在堆中開辟空間(根據成員變量的大小),并默認初始化成員變量
5、加載構造代碼塊,顯示初始化成員變量
6、加載構造方法,顯示初始化成員變量
7、將堆內存空間的首地址賦給對象的引用
靜態代碼塊,構造代碼塊案例
public class Demo{
public static int age;
static {
System.out.println("靜態代碼塊age-->" + age);
//初始化靜態成員變量,在類加載時執行
age = 20;
System.out.println("靜態代碼塊age-->" + age);
}
{ //構造代碼塊,可以被看成是一個無參的構造方法
age += 1;
System.out.println("構造代碼塊-->" + age);
}
public Demo() {
age += 1;
System.out.println("構造方法中: age-->" + age);
}
public static void main(String[] args) {
new Demo();
new Demo();
new Demo();
new Demo();
}
}
運行結果

類的繼承
關鍵字 extends,通過繼承,可以將父類的成員繼承過來,使得兩個存在父子關系
案例
public class Demo {
public static void main(String[] args) {
Person1 person1 = new Person1();
person1.setName("小李子");
person1.eat();//小李子,正在吃
Student2 s2 = new Student2();
s2.setName("賤人曾");
s2.eat();//賤人曾,正在吃
Worker worker = new Worker("xiaofeifei");
worker.eat();//xiaofeifei,正在吃
}
}
class Person1 { //父類
private String name;
public Person1() {
} //無參的構造方法
public Person1(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + ",正在吃");
}
}
class Student2 extends Person1 { //子類
}
class Worker extends Person1 { //子類
public Worker(String name) {
super(name); //調用父類的構造方法,super()必須在第一行
}
}
繼承中的構造、靜態代碼塊
繼承中的類成員特點
1、父類的私有成員不能被訪問
2、如果子類中存在成員與父類的成員重名,則使用super來訪問父類中同名成員,super是代表父類的數據空間,并不是一個對象
繼承中有靜態代碼塊,構造代碼塊時,對象的初始化過程
1、父類的靜態代碼塊
2、子類的靜態代碼塊
3、父類的構造代碼塊。。
4、父類構造方法-->初始化父類的成員變量
5、子類的構造代碼塊。。
6、子類構造方法-->初始化子類的成員變量
案例
public class Demo {
public static void main(String[] args) {
Child c1 = new Child();
c1.say();
}
}
class Parent {
private String name;
public int age;
static {
System.out.println("父類的靜態代碼塊。。");
}
{
System.out.println("父類的構造代碼塊。。");
}
public Parent() {
System.out.println("父類構造方法-->初始化父類的成員變量");
}
private void setName(String name) {
}
public void talk() {
System.out.println("父類 age:" + age);
}
}
class Child extends Parent { //子類,繼承父類的所有成員
private int age;
static {
System.out.println("子類的靜態代碼塊。。");
}
{
System.out.println("子類的構造代碼塊。。");
}
public Child() {
System.out.println("子類構造方法-->初始化子類的成員變量");
}
public void say() {
//name="張三";//出錯,父類的私有成員不能被訪問
//setName("張三");//同上
super.age = 100; //訪問父類的成員變量
age = 90; //訪問子類的成員變量
System.out.println("子類 age:" + age);
talk(); //非私有成員方法都能訪問
}
}
運行結果
