目录
1.面向对象初步认识
1.1什么是面向对象
Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。
1.2面向对象和面向过程的区别
传统洗衣服:
传统洗衣服注重的是面向过程,也就是按照步骤一步一步实现,少一个步骤都不行
每一种衣服鞋子清洗的方式都不同,处理起来就比较麻烦
如果我们按这种方式去写代码,后期对代码的扩展和维护就比较麻烦
现代洗衣服:
现代洗衣服方式中总共有4个对象:人,衣服,洗衣液,洗衣机
洗衣服的过程:人将衣服和洗衣液放进洗衣机,启动洗衣机
在整个洗衣服的过程中,人,衣服,洗衣液,洗衣机这4个对象交互完成了洗衣服这件事,而人并不需要关系衣服是怎么被搓干净和拧干净的
以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成的。
注意:面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。
2.类的定义和使用
2.1简单认识类
类是对一个实物(对象)的属性以及功能进行描述的
对比于现实生活中产品的说明书
在这个说明书里有产品的属性:产品名称,产品部件,型号等等
产品的功能:使用方法,安装,拆卸,清洁
2.2类的定义格式
java中定义一个类需要用到class关键字
class ClassName{ //ClassName为类名
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类 具有哪些功能,称为类的成员方法。
定义一个洗衣机的类
class Washer{
public String name; //名称
public int size; //大小
public String model; //型号
public String color; //颜色
public void function1(){ //洗衣功能
System.out.println("洗衣功能");
}
public void function2(){ //脱水功能
System.out.println("脱水功能");
}
}
在行业里,类名一般采用大驼峰的命名规则
2.3类的实例化
类相当于一份说明书,我们要完成某件事就需要一个这个类描述的实物来帮我们进行完成
当我们了解了这个类的功能和用途,我们就需要"买"这个类对应的产品,而"买"这个类对应的产品就叫类的实例化
用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
举例:
创建一个洗衣机类的对象
类名 对象名=new 类名();
Washer washer=new Washer();
这样实例化一个对象,washer就相当于我们买回来的那个产品了
注意事项:
1.new 关键字用于创建一个对象的实例.
2.使用 . 来访问对象中的属性和方法.
3.同一个类可以创建对个实例
2.4类和对象的说明
-
类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
-
类是一种自定义的类型,可以用来定义变量.
-
一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
-
做个比方,类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东 西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
对比一下:
3.this关键字
3.1访问本类成员变量
class Student{
private String name;
private int age;
private String id;
public Student(String name,int age,String id){
name=name;
age=age;
id=id;
}
public void show(){
System.out.println("我是"+name+",今年"+age+"岁了,我的id是"+id);
}
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student("小明",18,"2024511");
student.show();
}
}
先来看看这段代码它的输出结果
我相信你的第一反应应该是:我是小明,今年18岁了,我的id是2024511;
但输出结果是我是null,今年0岁了,我的id是null;
解释:
在这下面这段代码中
public Student(String name,int age,String id){
name=name;
age=age;
id=id;
}
我们认为左边的name,age,id是成员变量,但实际上在这段代码中左边的name,age,id是局部变量,此时局部变量给局部变赋值,没有给成员变量赋值,成员变量的值没有改变,依然是默认值
然而当构造方法中的形参名和成员变量名不相同时,就不会出现以上情况
class Student{
private String name;
private int age;
private String id;
public Student(String n,int a,String i){
name=n;
age=a;
id=i;
}
public void show(){
System.out.println("我是"+name+",今年"+age+"岁了,我的id是"+id);
}
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student("小明",18,"2024511");
student.show();
}
输出结果是:我是小明,今年18岁了,我的id是2024511
想要解决形参名与成员变量名相同时给成员变量赋值的问题就需要使用this关键字,this关键字表示本类中的成员变量和成员方法
public Student(String name,int age,String id){
this.name=name;
this.age=age;
this.id=id;
}
加上this就表示本类中的成员变量
在成员变量和局部变量重名时,优先使用局部变量,也就是就近原则。
3.2调用构造方法初始化成员变量
class Student{
private String name;
private int age;
private String id;
public Student(){
this("haha",12,"202451101");
}
public Student(String name,int age,String id){
this.name=name;
this.age=age;
this.id=id;
}
public void show(){
System.out.println("我是"+name+",今年"+age+"岁了,我的id是"+id);
}
}
在不带参数的构造方法中初始化成员变量,用this调用带三个参数的构造方法,直接在this后面的括号中填写对应的参数就行
在构造方法中使用this调用其他构造方法对成员变量进行初始化时this语句必须放在该构造方法的第一行
3.3this引用的特性
this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
this只能在"成员方法"中使用
在"成员方法"中,this只能引用当前对象,不能再引用其他对象
this是"成员方法"第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收 在代码层面来简单演示--->注意:下图右侧中的Date类也是可以通过编译的
4.对象的构造以及初始化
4.1就地初始化与默认初始化
在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
public static void main(String[] args) {
int a;
System.out.println(a);
}
//运行结果:java: 可能尚未初始化变量a
所以在创建局部变量时需要在使用变量之前对变量进行初始化
但是在创建类时,对类进行实例化后调用成员变量时我们会发现,编译器没有报错,这是为什么呢?
class Date{
private int year;
private int month;
private int day;
private String zodiac;
public void setDate(int y, int m, int d) {
year = y;
month = m;
day = d;
}
public void show(){
System.out.println("year:"+year+" month:"+month+" day: "+day+" zodiac"+zodiac);
}
}
public class Test01 {
public static void main(String[] args) {
Date date=new Date();
date.show();
}
}
这是因为我们在实例化对象时,编译器默认的给我成员变量赋值了
当然我们不需要默认初始化的值可以就地初始化,也就是创建类的时候就给成员变量赋值
class Date{
private int year=2024;
private int month=5;
private int day=12;
}
4.2构造方法
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
4.2.1默认构造方法
class Date{
private int year=2024;
private int month=5;
private int day=12;
// 构造方法:
// 名字与类名相同,没有返回值类型,设置为void也不行
// 一般情况下使用public修饰
// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public void show(){
System.out.println("year:"+year+" month:"+month+" day: "+day);
}
}
当我们实例化对象时下面这样写会报错
这是为什么呢,我们没写构造方法前是对的,反而写了就错了。难道我们写的代码有问题?
这是因为编译器有一个就穷不救急的性格,当我们没有构造方法时,他会提供一个默认的构造方法,当我们写了构造方法,他就不提供默认的构造方法了,如果想使用默认的构造方法就必须自己在类里面写一个
public Date(){
}
添加一个这样的类就行了,方法体什么都不写
4.2.2构造方法的特性:
名字必须与类名相同
没有返回值类型,设置为void也不行
创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
public Date(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public Date(int year, int month) { this.year = year; this.month = month; }
上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载。
4.2.3构造方法中,通过this调用其他构造方法
在构造方法中,可以通过this调用其他构造方法来简化代码
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public Date(int year, int month) {
this.year = year;
this.month = month;
}
public Date(){
this(1900,2,12);
}
在构造方法中使用this调用其他构造方法时,要注意在这个构造方法中方法的重载问题
public Date(){
}
public Date(){
this(1900,2,12);
}
比如这样,我们写的默认构造方法和this的构造方法形参一样,编译器就会报错
注意:
1.this在构造方法中必须是第一条语句
2.this调用其他构造方法时不能成环
public Date(){
this(1900,1,1);
}
public Date(int year, int month, int day) {
this();
}
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用