1.类的定义与使用
1.1 认识类
简单来说类就是对一个实体进行描述,主要描述该实体对象有哪些属性,什么功能,用来做什么,这样计算机就可以识别了。
1.2 类的定义格式
在Java中定义类时需要用到class关键字,具体语法如下。
class ClassName{
field; //字段或是成员属性
method; //成员方法
}
class为定义类的关键字,ClassName为类的名字,{}中为主体。类中包含的内容称为类的成员,属性主要用来描述类的,称为类的成员属性或者类成员变量。类的属性(字段)和成员变量定义在类当中,且在方法的外边。
class WashMachine{
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double length; // 长
public double width; // 宽
public double height; // 高
public String color; // 颜色
public void washClothes(){ // 洗衣服
System.out.println("洗衣功能");
}
public void dryClothes(){ // 脱水
System.out.println("脱水功能");
}
public void setTime(){ // 定时
System.out.println("定时功能");
}
}
采用Java语言将洗衣机类在计算机中定义完成,经过javac编译之后形成.class文件,在JVM的基础上计算机就可以识别了。
注意事项
- 类名要用大驼峰定义
- 成员前写法统一为public
- 此处写的方法不带static关键字
2.类的实例化
2.1 什么是实例化
定义一个类,相当于在计算机中定义了一种新的类型,与int,double类似,但这些是Java语言自带的内置类型,而类是用户自定义的新的类型,那么就可以通过自定义类来定义实例(创建对象)
用类的类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象
class Student{
public String name;
public int age;
public void grades(){
System.out.println(this.name+"总成绩510分");
}
public void like(){
System.out.println(this.name+"喜欢敲代码");
}
}
public class Test {
public static void main(String[] args) {
Student student1=new Student();
student1.name="张三";
student1.age=18;
student1.grades();
student1.like();
Student student2=new Student();
student2.name="李四";
student2.age=19;
student2.grades();
student2.like();
}
}
输出结果:
张三总成绩510分
张三喜欢敲代码
李四总成绩510分
李四喜欢敲代码
注意事项
- new关键字用于创建一个对象的实例。
- 使用.来访问对象中的属性和方法。
- 同一个类可以创建多个实例。
2.2 类和对象的说明
- 类只是一个模型,用来对实体进行描述,在实体中有成员属性和成员方法。
- 类是一种自定义的类型,可以用来定义变量。
- 一个类可以实例化多个对象,实例出来的对象占用实际的物理空间,存储成员变量
- 比如,做房子,设计图纸是类,图纸怎样设计就是怎样定义属性,实际做出来的房子就是类实例化出来的对象,正是存在且占用实际的物理空间。
3.this引用
3.1 为什么要有this引用
简单来说有了this引用那么就可以,引用当前对象的属性,那么即便在遇到形参名与成员变量名相同时,对象能够准确调用成员方法,并且能够知道对应的对象的数据。
举个例子
public class Date {
public int year;
public int month;
public int day;
public void setDay(int y,int m,int d){
year=y;
month=m;
day=d;
}
public void printDate(){
System.out.println(year+"/"+month+"/"+day);
}
public static void main(String[] args) {
Date d1=new Date();
Date d2=new Date();
Date d3=new Date();
d1.setDay(2020,9,15);
d2.setDay(2020,9,16);
d3.setDay(2020,9,17);
d1.printDate();
d2.printDate();
d3.printDate();
}
}
上面代码定义了一个日期类,然后在main方法中创建了三个对象,并通过Date类的成员方法对对象进行设置和打印,那么形参名相同时
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}
那么结果就是一连串的零,因为这时三个对象同时调用setDay和printDay函数,这两个成员方法无法准确作用于实例化的对象当中的数据,那么this很好的解决了这个问题。
3.2 什么是this引用
简单来说this就是代表当前对象的引用,this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year + "/" + this.month + "/" + this.day);
}
}
注意:this引用的是调用成员方法的对象 ,date指向的对象就是this指向的对象,所以this代表和date指向同一个对象的引用。
3.3 this引用的特性
- this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型。
- this只能在“成员方法”中使用
- 在“成员方法”中,this只能引用当前对象,不能引用其他对象
- this还是“成员方法”的一个隐藏参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this来负责接收。
4.对象的构造及初始化
4.1 如何初始化对象
使用构造方法对成员变量进行初始化,那什么是构造方法,构造方法(也称构造器)是一个特殊的成员方法,名字必须和类名相同,没有返回值,一般情况下使用public修饰,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只能调用一次。
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
4.2 构造方法特性
- 名字必须与类名相同
- 没有返回值类型,设置void也不行
- 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
- 构造方法可以重载也就是说用户可以根据自己的需求提供不同参数的构造方法
public class Date {
public int year;
public int month;
public int day;
//无参数构造方法
public Date(){
this.year=2024;
this.month=3;
this.day=10;
}
//带有三个参数构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year+"-"+month+"-"+day);
}
public static void main(String[] args) {
Date d=new Date();
d.printDate();
}
上面代码由两个构造方法,名字相同,参数列表不同,因此构成了方法重载,注意如果用户没有定义构造方法,编译器会生成一份默认无参数的构造方法,一旦用户定义,编译器则不再生成这个默认的构造方法。
还有一个点就是局部变量在使用时一定要初始化,而成员变量可以不用,这是因为对象空间被申请好后,对象中的成员已经设置好了初始值,还有在声名变量时可以直接就给初始值,这也叫就地初始化。
5.封装
5.1 什么是封装
面向对象程序三大特性:封装、继承、多态。在这一节封装简要来说就是套壳隐蔽细节,实际就是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
5.2 访问权限限定符
- private:范围:同一包中的同一类
- default:范围:同一包中的同一类、同一包中不同类
- protected:范围:同一包中的同一类、同一包中不同类、不同包中的子类
- public:范围:同一包中的同一类、同一包中不同类、不同包中的子类、不同包中的非子类
【说明】
- protected主要用在继承中
- default权限指:什么都不写时的默认权限
- 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
6.static成员
6.1 学生类当中的static
使用学生类实例化三个对象s1,s2,s3 ,每个对象都有自己的名字,性别,年龄,学分绩点等信息,这就是对不同的学生进行描述。
public class Std {
public String name;
public String sex;
public int age;
public double score;
public Std(String name, String sex, int age, double score) {
this.name = name;
this.sex = sex;
this.age = age;
this.score = score;
}
public static void main(String[] args) {
Std s1=new Std("张三","男",18,3.1);
Std s2 = new Std("李四", "女", 19, 4.0);
Std s3 = new Std("王五", "男", 18, 2.6);
}
}
那么如果这位同学时是同一个班的,那么它们就是共有一个班级,这时就不需要每个学生对象都存储一份,而是让所有学生共享。那么在java语言中,被static修饰的成员,也可以称为类成员,其不属于某个具体的对象,是所有对象共享的。
6.2 static修饰成员变量
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有的对象共享的。
【静态成员变量特性】
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存在某个对象的空间中
- 既可以通过类对象访问,也可以通过类名访问,但更建议使用类名访问
- 类变量存储在方法区当中
- 生命周期:随类的加载而创建,随类的卸载而销毁
public class Std {
public String name;
public String sex;
public int age;
public double score;
public static String classRoom="111";
public Std(String name, String sex, int age, double score) {
this.name = name;
this.sex = sex;
this.age = age;
this.score = score;
}
public void printStudent(){
System.out.println(this.name+" "+this.sex+" "+this.age+" "+this.score+" "+this.classRoom);
}
public static void main(String[] args) {
System.out.println(Std.classRoom);
Std s1=new Std("张三","男",18,3.1);
Std s2 = new Std("李四", "女", 19, 4.0);
Std s3 = new Std("王五", "男", 18, 2.6);
s1.printStudent();
s2.printStudent();
s3.printStudent();
//也可以通过对象访问
System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);
}
}
通过监视窗口也可以看到静态成员变量并没有从存储到某个具体的对象中。
6.3 static修饰成员方法
一般类中的数据成员都设置为private,而成员方法设置为public,那设置之后,Student类中的classRoom属性如何再类外访问呢?
Java中,被static修饰的成员方法称之为静态成员方法,是类的方法,不是某个对象所特有的,静态成员一般是通过静态方法来访问的。
public class Student{
// ...
private static String classRoom = "Bit306";
// ...
public static String getClassRoom(){
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
【静态方法特性】
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过类名.静态方法()方式调用,推荐后者
- 不能在静态方法中访问任何非静态成员变量
-
静态方法中不能调用任何非静态方法,因为非静态方法由this参数,在静态方法中调用时无法转递this引用
6.4 static成员变量初始化
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化就是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化和静态代码块初始化。
7.对象的打印
public class Std {
public String name;
public String sex;
public int age;
public double score;
public static String classRoom="111";
public Std(String name, String sex, int age, double score) {
this.name = name;
this.sex = sex;
this.age = age;
this.score = score;
}
public static String getClassRoom(){
return classRoom;
}
public void printStudent(){
System.out.println(this.name+" "+this.sex+" "+this.age+" "+this.score+" "+this.classRoom);
}
public static void main(String[] args) {
System.out.println(Std.classRoom);
Std s1=new Std("张三","男",18,3.1);
Std s2 = new Std("李四", "女", 19, 4.0);
Std s3 = new Std("王五", "男", 18, 2.6);
/*s1.printStudent();
s2.printStudent();
s3.printStudent();*/
//也可以通过对象访问
//System.out.println(Std.getClassRoom());
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
/*System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);*/
}
}
运行结果:
111
Std@4eec7777
Std@3b07d329
Std@41629346
那么如果要默认打印对象中的属性该如何处理呢,在这只需要重写toString方法即可
鼠标右键下拉框选择Generate,再选择toString就可以快速完成重写
public class Std {
public String name;
public String sex;
public int age;
public double score;
public static String classRoom="111";
public Std(String name, String sex, int age, double score) {
this.name = name;
this.sex = sex;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Std{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", score=" + score +
'}';
}
public static String getClassRoom(){
return classRoom;
}
public void printStudent(){
System.out.println(this.name+" "+this.sex+" "+this.age+" "+this.score+" "+this.classRoom);
}
public static void main(String[] args) {
System.out.println(Std.classRoom);
Std s1=new Std("张三","男",18,3.1);
Std s2 = new Std("李四", "女", 19, 4.0);
Std s3 = new Std("王五", "男", 18, 2.6);
/*s1.printStudent();
s2.printStudent();
s3.printStudent();*/
//也可以通过对象访问
//System.out.println(Std.getClassRoom());
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
/*System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);*/
}
}
输出结果:
111
Std{name='张三', sex='男', age=18, score=3.1}
Std{name='李四', sex='女', age=19, score=4.0}
Std{name='王五', sex='男', age=18, score=2.6}
本节完......