Java SE - 类和对象入门指南
目录
- 1.类的创建
- 2.类的使用
- 2.1 实例化对象
- 2.2 成员的初始化
- 2.3 成员方法的调用
- 2.4 this关键字
- 2.5 构造方法
- 2.6 重写toString方法
- 3.包的概念
- 4.封装
- 5.访问限定符
- 5.1 public访问限定符
- 5.2 defaul访问修饰符
- 5.3 protected和private访问修饰符
- 6.static修饰的成员
- 7.代码块
- 7.1 普通代码块
- 7.2 实例代码块
- 7.3 静态代码块
1.类的创建
类是将相同的属性和行为进行集中归类,当需要使用类时,通过类实例化对象,通过对象可以访问到类中的属性和行为;类的创建需要使用一个关键字class,声明该类型是一个类。
//创建一个Animal类
class Animal {//属性:成员变量//行为:成员方法
}
动物这一个类包含的属性可以有名字,年龄,性别等;行为有吃,睡觉等;可以将这些共同的属性或行为进行创建。
//创建一个Animal类
class Animal {//属性:成员变量public String name;public int age;public String sex;//行为:成员方法//eat方法public void eat(){System.out.println("Animal在吃饭.....");}//sleep方法public void sleep(){System.out.println("Animal在睡觉......");}
}
了解以上类是由属性和行为所构成的,类比创建一个Cat (猫)类,包含成员方法和属性,猫的属性包括名字,年龄,颜色等;行为包括吃饭睡觉,发出声音等,通过这些实现以下类。
//创建一个Cat类
class Cat {//属性:成员变量public String name;public int age;public String color;//行为:成员方法//eat方法public void eat(){System.out.println(name + "在吃饭......");}//sleep方法public void sleep(){System.out.println(name + "在睡觉......");}//声音public void mem(){System.out.println(name + "在喵喵喵......");}
}
2.类的使用
2.1 实例化对象
类声明后就可以创建对象,对象的实例化可以通过new关键字进行创建。
public static void main(String[] args) {//类名 + 变量名 new 类名();Cat cat = new Cat();}
2.2 成员的初始化
实例化对象后就可以访问到类中的成员变量(属性),使用 ’变量名 + 点 + 成员变量名‘的方式访问到成员变量并初始化赋值。
public static void main(String[] args) {//类名 + 变量名 new 类名();Cat cat = new Cat();//初始化cat.name = "花花";cat.age = 20;cat.color = "orange";//输出System.out.println("Cat:" + cat.name + " " + cat.age + " " + cat.color );}
2.3 成员方法的调用
class MyDate{//成员变量int year;int month;int day;//成员方法void print(int y,int m,int d){year = y;month = m;day = d;System.out.println("日期:" + year + " " + month + " " + day);}
}public class Main{public static void main(String[] args) {//实例化对象MyDate myDate = new MyDate();//访问类中的方法:引用 + 成员方法名myData.print(2024,5,10);}
}
实例化对象后将在堆区开辟空间的起始地址赋给引用类型myDate,通过引用类型就可以访问到类中的成员方法。
2.4 this关键字
当成员方法发的参数与成员变量名一样时,优先使用的是成员方法的参数。
class MyDate{//成员变量int year = 2024;int month = 5;int day = 20;//成员方法void print(int year,int month,int day){System.out.println("日期:" + year + " " + month + " " + day);}
}public class Main{public static void main(String[] args) {//实例化对象MyDate myDate = new MyData();//访问类中的方法:引用 + 成员方法名myData.print(2024,5,10);}
}
如果需要使用成员变量,可以使用this关键字,this关键字的作用是对引用进行替换。
class MyDate{//成员变量int year = 2024;int month = 5;int day = 20;//成员方法void print(int year,int month,int day){//print方法是myDate引用调用的,this替换的就是myDate这个引用//this.year表示myDate指向的类中的year,即2024//this.month表示myDate指向的类中的month,即5//this.day表示myDate指向的类中的day,即20System.out.println("日期:" + this.year + " " + this.month + " " + this.day);}
}public class Main{public static void main(String[] args) {//实例化对象MyData myData = new MyData();//访问类中的方法:引用 + 成员方法名myData.print(2024,5,10);}
}
2.5 构造方法
构造方法是对成员变量在实例化对象的同时进行初始化,一般成员变量由多少个,构造方法就可以指定多少个参数的构造方法,构造方法一般由public + 类名构成。
//声明一个学生类
class Student{//成员变量String name;//名字int age;//构造方法:public + 类名 构成public Student(String name, int age){//this替换引用:指向成员变量this.name = name;//参数的namethis.age = age;//参数的age}}
在类中创建构造方法,在实例化的对象的同时给成员变量赋值。
public static void main(String[] args) {//实例化对象Student student1 = new Student("笑笑",20);Student student2 = new Student("王王",12);}
2.6 重写toString方法
调用构造方法初始化成员变量后,将对象输出打印。
//声明一个学生类
class Student{//成员变量String name;//名字int age;//构造方法:public + 类名 构成public Student(String name, int age){//this替换引用:指向成员变量this.name = name;//参数的namethis.age = age;//参数的age}}
public class Main{public static void main(String[] args) {//实例化对象Student student1 = new Student("笑笑",20);Student student2 = new Student("王王",12);//输出System.out.println(student1);System.out.println(student2);}
观察到实际输出的并不是引用指向对象的成员变量内容,原因是在类中没有重写toString方法,具体原因可以按住Ctrl键点击println函数。跳转到println函数实际调用的原码。
最后跳转到toString方法,因此println的使用实际调用的是toString方法,实际输出的内容是 “类名 + @ + 地址”,与预期输出的内容不一致,预期输出的是成员变量的内容,因此就需要重写toString方法,
在IDEA中可以由快速生成重写toString的方式,鼠标点击右键找到generate,选择constructor,按住Ctrl键点击选择重写方法中的包含的成员变量,即可生成重写的toString方法。
//重写toString方法@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
再次运行程序就可以输出成员变量的内容。
3.包的概念
包类似于文件夹,一个包中可以包含多个文件,一般一个文件中包含一个类(但是也可以包含多个),有了包可以进行分类使用,需要在不同的文件使用其它包时,导包就可以访问到包中定义的类。
包的创建:创建项目后找到src,右键选择New中Package点击。
此时包就创建好了,在创建好的包中创建类,右键找到new,找到Java Class点击。
此时就创建好一个Test类,类中可以创建成员变量和成员方法。
package Demo;public class Test {//成员变量int a;int b;//构造方法public Test(int a,int b){this.a = a;this.b = b;}//成员方法void print(){System.out.println(this.a);}
}
4.封装
Java是一门面向对象的语言,其中三大特性是封装,继承和多态,而封装就是类和对象中的一大特性,使用封装可以使类中的成员变量或方法不被直接的访问,在类中使用方法获取封装成员变量或方法,在实例化对象的过程中,通过引用间接的访问封装成员变量或方法,有效的保护类内部的具体实现过程。
class MyData{//使用private修饰成员变量//该成员变量只能在当前类中使用private int data1;private int data2;//封装成员变量,调用初始化方法public void setData(int data1,int data2) {this.data1 = data1;this.data2 = data2;}//封装的data需要调用方法获取public int getData1(){return data1;}public int getData2() {return data2;}
}public class Test{public static void main(String[] args) {//实例化对象MyData myData = new MyData();//调用封装成员变量的初始化方法myData.setData(20,30);//调用封装的方法获取成员变量int myData1 = myData.getData1();int myData2 = myData.getData2();//输出获取到的封装成员变量System.out.println("myData1 = " + myData1);System.out.println("myData2 = " + myData2);}
}
封装的好处
-
降低代码的耦合性
封装可以降低对象和对象之间的耦合度,当对象内部发⽣变化时,只需要修改对象内部即可,不影响到外部程序,因为公开的接⼝是不会发⽣改变的 -
降低代码的复杂性
封装是隐藏了对象内部的实现细节,只提供了公开的接⼝给外部,使⽤起来更加简单 -
提⾼安全性
封装可以隐藏对象的具体实现细节,阻⽌外部程序直接访问对象的内部状态,从⽽保护数据不被意外的修改或破坏。
5.访问限定符
public修饰的类或者字段和方法,使用的范围是同一个类中使用,同一个包的不同类中使用,不同包的子类中使用,不同包的类中使用;
protected修饰的字段或方法可以在同一个类中使用,同一个包的不同类中使用,不同包的子类中使用;
default(默认类型)修饰的类或字段和方法只能在同一个包的同一个类或不同类中使用;
private修饰的字段或方法只能当前类中使用。
5.1 public访问限定符
在Demo2包中创建一个Stu类,在不同包中的文件中创建一个Main类,实现Stu类使用public修饰类型,字段和成员方法,被修饰过后Stu类可以在不同包的不同类中使用,此处在Main类中实例化Stu的对象,通过对象的引用调用类中的方法。
package Demo2;//public修饰的
public class Stu {//成员public String name;public int age;public Double score;//构造方法public Stu(String name, int age,Double score) {this.name = name;this.age = age;this.score = score;}@Override//重写toString方法public String toString() {return "Stu{" +"name='" + name + '\'' +", age=" + age +", score='" + score + '\'' +'}';}
}
public class Main{public static void main(String[] args) {//实例化对象Stu stu = new Stu("张三",20,90.00);//输出System.out.println(stu);}
}
5.2 defaul访问修饰符
在Demo中创建一个bird (鸟)类,修饰符是默认类型不需要写,只需要使用class关键字修饰声明类,在Demo中在创建一个Main类,在Main类中实例化Bird类对象,调用类中的方法。
package Demo2;//鸟类,默认类型
class Bird {//成员变量String name;int age;public Bird(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Bird{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package Demo2;//使用Bird类
class Main {public static void main(String[] args) {//实例化Bird bird = new Bird("九九",3);//输出System.out.println(bird);}
5.3 protected和private访问修饰符
protected和private不能修饰直接类,一般用于修饰类中的成员变量和方法,protected的使用与public类似,区别在于protected修饰的在不同包中只能被子类中使用,private修饰的成员和方法只能在类中使用。以protected修饰的为例:在Demo1创建一个父类Animal和一个子类Cat,父类的成员和方法使用protected修饰,在子类中实例化对象,通过引用调用父类被protected修饰的成员和方法。
package Demo1;//创建一个Animal类:成员和方法由protected修饰
public class Animal {//属性:成员变量protected String name;protected int age;protected String sex;protected String color;//行为:成员方法//eat方法protected void eat(){System.out.println("Animal在吃饭.....");}//sleep方法protected void sleep(){System.out.println("Animal在睡觉......");}
}
package Demo1;//创建一个Cat类:extends表示继承
public class Cat extends Animal {//行为:成员方法@Override//eat方法重写public void eat(){System.out.println(name + "在吃饭......");}@Override//sleep方法重写public void sleep(){System.out.println(name + "在睡觉......");}public void mem(){System.out.println(name + "在喵喵喵......");}public static void main(String[] args) {//类名 + 变量名 new 类名();Cat cat = new Cat();//初始化cat.name = "花花";cat.age = 20;cat.color = "orange";//输出System.out.println("Cat:" + cat.name + " " + cat.age + " " + cat.color );}
}
输出结果:
6.static修饰的成员
static修饰的成员是类成员,不会随实例化对象的增多而多创建多个静态变量,静态变量在程序加载的过程只被加载一次,存放于方法区。
//声明一个学生类
class Student{//成员变量String name;//名字int age;static String Class;//静态成员变量
}
static修饰的成员是类成员,可以通过类名 + .(点) + 静态成员变量名的方式初始化,也可以在创建的同时初始化。
//声明一个学生类
class Student{//成员变量String name;//名字int age;static String Class = "1班";//静态成员变量
}
public class Main {public static void main(String[] args) {//类名 + 点 + 变量名Student.Class = "1班";}
7.代码块
7.1 普通代码块
普通代码块是被{}包含的语句,例如在main函数中使用普通代码块。
public class Main{public static void main(String[] args) {int x;//执行{}普通代码块{x = 10;System.out.println("普通代码块被执行了,x = " + x);}}
}
7.2 实例代码块
实例化代码块也称构造代码块,一般是用于在类中初始化成员变量。
class Test{//成员int a;int b;//构造方法public Test(){System.out.println("构造方法执行了......");}//实例化代码块{this.a = 20;this.b = 30;System.out.println("构造代码块执行了.......");}void show(){System.out.println("a = " + a + " b = " + b);}
}public class Main{public static void main(String[] args) {Test test = new Test();test.show();}
}
以上程序的输出结果:在类中构造代码块的执行比构造方法的执行快,与顺序无关。
7.3 静态代码块
静态代码块用于初始化类中的静态成员变量。
class Test{//成员int a;int b;static char[] chars;//构造方法public Test(){System.out.println("构造方法执行了......");}//实例化代码块{this.a = 20;this.b = 30;System.out.println("构造代码块执行了.......");}//静态代码块static{char[] chars1 = {'H','e','l','l','o'};System.out.println("静态代码块执行了......");}void show(){System.out.println("a = " + a + " "+ "b = " + b);}public static void main(String[] args) {Test test = new Test();test.show();}
}
以上程序的输出结果:静态代码块最先被执行,随后是构造代码块,最后是构造方法,静态代码块在程序中只加载一次,不会随实例化对象的增加而多次加载。
class Test{//成员int a;int b;static char[] chars;//构造方法public Test(){System.out.println("构造方法执行了......");}//实例化代码块{this.a = 20;this.b = 30;System.out.println("构造代码块执行了.......");}//静态代码块static{char[] chars1 = {'H','e','l','l','o'};System.out.println("静态代码块执行了......");}void show(){System.out.println("a = " + a + " "+ "b = " + b);}public static void main(String[] args) {Test test = new Test();System.out.println("=================");Test test1 = new Test();}
}