一.面向对象的初步认知
1.什么是面向对象
Java是一门纯面向对象的语言{简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来设计程序,更符合人们对事物的认知,对于大型程序的设计,扩展以及维护都非常友好
2.面向对象和面向过程
1.传统洗衣服过程
而且洗不同的衣服或者东西方式都不同,按照该种方式来写代码,将来扩展或者维护起来会比较麻烦
2.现代洗衣服过程
总共有四个对象:人,衣服,洗衣粉,洗衣机
过程:人将衣服放进洗衣机,倒入洗衣粉,启动洗衣机,洗衣机就会完成洗衣过程并且甩干
整个过程主要是:人,衣服,洗衣粉,洗衣机四个对象之间交互完成的,人不需要关心洗衣机具体是如何洗衣服如何甩干的
以面向对象方式来处理,就不关注洗衣服的过程,具体洗衣机是怎么洗衣服,怎么甩干,用户不用去关心,只需将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成的
注意:面向过程和面向对象并不是一门语言,而是解决问题的方法,没有好坏之分,都有其专门的应用场景
二.类定义和使用
面向对象程序设计关注的是对象,而对象是现实生活中的载体,比如洗衣机。但是计算机并不认识洗衣机,需要开发人员告诉计算机什么是洗衣机
上图左侧就是对洗衣机简单的描述,该过程称为对洗衣机对象(实体)进行抽象(对一个复杂事物的重新认知),但是这些简化的抽象结果计算机也不能识别,开发人员可以采用某种面向对象的编程语言来进行描述,比如Java
1.简单认识类
类是对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成后计算机就可以识别了。
2.类的定义格式
在Java中定义类时需要用到class关键字
类中包含的内容称为类的成员。属性主要用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明具有哪些功能,称为类的成员方法
定义一个狗类型
注意:
类名要使用大驼峰形式
成员前写法统一为public
此处写的方法不带static关键字
一般一个文件当中只定义一个类
main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
public修饰的类必须要和文件名相 同
不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改
只适用于一个Java文件只有一个类
三.类的实例化
1.什么是实例化
通过new关键字,实例化了一个Dog对象
dog就是一个引用,指向了Dog对象
同样也可以使用Dog类型定义多个狗,比如:
new关键字用于创建一个对象的实例
使用.来访问对象中的属性和方法
同一个类可以创建多个对象
2,类和对象的说明
1,类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
2.类是一种自定义类型,可以定义变量
3.一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量
4.类实例化出对象就像使用建筑设计图建造出来的房子,类就像是设计图,只需要设计出需要什么东西,但并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
四.this引用
this代表当前对象的引用
1.为什么要有this引用
这个代码有两个问题
1.形参名不小心和成员变量名相同
那此时不确定是谁在给谁赋值
2.三个对象都在调用setData和printData函数,但是这两个函数中没有任何有关对象的说明,setData和printData函数如何知道打印的是哪个函数呢?
此时需要用到this
2.什么是this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问只不过所有操作对用户是透明的,即用户不需要来传递,编译器自动完成
所有建议在写成员方法时都用this
3.this引用的特性
this的类型:对应类类型引用,即哪个对象调用哪个对象的引用类型
this只能在“成员方法”中使用
在“成员方法”中,this只能引用当前对象,不能再引用其他对象
this是成员方法的第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责接收
五.对象的构造和初始化
1.如何初始化对象
局部变量在使用前一定要初始化,否则会报错
而成员变量不是局部变量
当成员变量没被初始化时,引用类型一般默认为null,基本类型默认是自己的0值
那成员变量如何初始化呢?
2.构造方法
1.概念
构造方法非常特殊:
1.方法名必须和类名相同
2.没有返回值
构造方法(也称为构造器)是一个特殊的成员方法,在创建对象时,由编译器自动调用,并且在整个对象的声明周期内只调用一次
当类中无构造方法时,Java会自动提供一个不带参数的构造方法
这里就调用了Data这个构造方法
Data d = new Data(2021 , 6 , 9);
构造方法之间可以构成方法的重载
构造方法的作用就是对对象中的成员进行初始化,不负责开辟空间
那自己怎么写构造方法呢?
右键generate-constructor
2.特性
1.名字必须和类名相同
2.没有返回类型,设置为void也不行
3.创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
4.构造方法可以重载
上面两个方法:名字相同,参数列表不同,构成了方法重载
5.如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的构造方法一定是无参的
public class Date {
public int year;
public int month;
public int day;
public void printDate(){
System.out.println(year+"-"+month+"-"+day);
}
public static void main(String[] args) {
Date d = new Date(); //这里会自动调用构造方法
d.printDate();
}
}
上述Date类中,没有定义构造方法,编译器会默认生成一个不带参数的构造方法
此时输出:0-0-0
一旦用户定义,编译器则不再生成
public class Date {
public int year;
public int month;
public int day;
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(2024 ,4 ,10);
d.printDate();
}
}
6.构造方法中,可以通过this调用其他构造方法,但只能放第一排
public class Date {
public int year;
public int month;
public int day;
//无参构方法-内部给各个成员赋初值,该部分功能与三个参数的构造方法重复
//此处可以在无参构造方法中通过this调用带有三个参数的构造方法
//但是this(1900,1,1);必须是构造方法中第一条语句
public Date() {
//System.out.println(year); 注释取消会报错
this(1900,1,1);
// this.year = 1900;
// this.month = 1;
// this.day = 1;
}
//带有三个参数的构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
7.绝大部分用public修饰,特殊场景会被private修饰
3.就地初始化
在声明成员变量时,就直接给了初始值
六.封装
1.封装的概念
面向对象程序三大特性:封装,继承,多态。而类和对象阶段,主要研究的就是封装特性。封装就是套壳屏蔽细节
封装:将数据和操作的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互
2.访问限定符
Java中主要通过类的和访来实现封装;类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符
说明:
protected主要用在继承中
default权限:什么都不写时的默认权限
访问权限除了可以限定成员的可见性,也可以控制类的可见性
3.封装扩展之包
1.概念
为了更好的管理类,把多个类收集在一起成为一组,称为软件包,类似目录
2.导入包中的类
但是这种写法麻烦,可以使用import语句导入包
如果需要使用Java.utill中的其他类,可以使用import java.utill.*
但更建议显式的指定要导入的类名,否则容易出现冲突的情况
这种情况下需要使用完整的类名
3.自定义包
- 创建包
- 在弹出的对话框中输入包名
- 在包中创建类,右键包名-新建-类,然后输入类名即可
- 同时在新创建的文件上方,就会出现一个package语句
- 常见的包
七.static成员
注意:static只能修饰成员变量,不能修饰局部变量
1.学生类
2.static修饰成员变量
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的
静态成员变量特性:
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象空间中
- 即可以通过对象访问,也可以通过类名访问,但一般推荐类名访问
- 类变量存储在方法区中
- 生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁
3.static修饰成员方法
静态方法特性:
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过类名.静态名(...)方式调用,推荐使用后者
- 不能在静态方法中直接访问任何非静态成员变量,但可以通过引用访问(new)
- 静态方法中不能直接调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时无法传递this引用
public static String getClassRoom(){ doClass(); return ClassRoom(); } //编译报错:无法从静态上下文中引用过非静态方法doClass()
4.static成员变量初始化
静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化和静态代码块初始化
- 就地初始化:在定义时直接给出初值
- 静态代码块初始化:得先了解什么是代码块
八.代码块
1.代码块概念以及分类
使用{}定义的一段代码叫做代码块。根据代码块定义的位置以及关键字,又可分为四种
- 普通代码块
- 构造块
- 静态块
- 同步代码块
2.普通代码块
就是定义在方法中的代码块
public class Main {
public static void main(String[] args) {
{//直接使用{}定义,普通方法块
int x = 10;
System.out.println("x1="+x);
}
int x = 100;
System.out.println("x2="+x);
}
}
//执行结果
x1=10
x2=100
这种用法较少见
3.构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
调用时实例代码块的代码比构造方法更先执行
4.静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
注意:
- 静态代码块不管生成多少个对象,其只会执行一次
- 静态成员变量是类的属性,因此在JVM加载类时开辟空间并初始化的
- 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
- 实例代码块内部只有在创建对象时才会执行
九.对象的打印
如果直接sout(方法),会输出它的地址
那怎么想要默认打印对象中的属性呢?重写toString方法即可
toString:右键-general-toString