1. 类和对象
1.1 什么是类和对象
万物皆对象,客观存在的事物皆为对象。
字面意思:人关注着对象
类是模子,确定对象将会拥有的特征(属性)和行为(方法)。
类的特点:
- 类是对象的类型
- 具有相同属性和方法的一组对象的集合
属性:对象具有的各种特征(可以理解为:这个对象有什么,比如:手机有屏幕 ---- 6.1英寸,有内存---- 8G,有存储 ---- 128G)
每个对象的每个属性都拥有特定值(比如上面的手机,其屏幕属性的特定值就是 6.1英寸),这些特定值就称为属性
对象执行的操作(或者理解为:对象能干什么,比如:手机能打电话,能发短信等)
类是抽象的概念,仅仅是模板,而对象是实实在在的实体,比如说:“手机”对象是一个你能看得到、摸得着的具体实体。
1.2 如何定义Java中的类
比如:我们在写一个面向对象程序的时候,类就是我们最基本的元素,我们必须先写一个类,才可以有对象。
前面我们说过什么是类,类是模子,确定对象将会拥有的特征(属性)和行为(方法)。
类的组成:属性和方法。定义一个类的步骤如下:
- 第一步:定义类名
- 第二步:编写类的属性
- 第三步:编写类的方法
如下:
public class 类名{
//定义属性部分(成员变量)
属性1的类型 属性1;
属性2的类型 属性2;
属性3的类型 属性3;
.....
属性n的类型 属性n;
//定义方法部分
方法1;
方法2;
方法3;
......
方法m;
}
我们来看一个“手机”类的Demo,如下:
打开idea,首先新建一个java项目File-->New-->Project 弹框如下:
这里只需要悬赏自己本地的jdk就可以,直接点击[Next],弹框如下:
我们这里勾上创建模板(会默认带上main方法),然后点击[Next],弹框如下:
在这里我们输入项目名、项目工作空间,以及项目包名,然后点击[Finish],弹框如下:
通过上面几个步骤,我们在idea中创建了一个java项目。
然后在com.example右键-->New-->Java Class,如下:
接下来就在新建的Telephone.class这个类中进行下面的步骤,声明类的属性和方法,如下:
package com.example;
//1.定义一个类
public class Telephone {
//2.属性(也叫 成员变量) ---> 代表 有什么
float screen;
float cpu;
float mem;
//3.方法 ----> 代表 干什么
void call() {
System.out.println("Telphone具有打电话的功能!");
}
void sendMessage() {
System.out.println("Telphone具有发短信的功能!");
}
}
到这里,我们就创建了一个叫做 “手机” 的类。
1.3 如何定义Java中的对象
上一节我们已经知道了如何去定义一个类,那么,我们怎么去把一个定义好的类变成对象,进而使用对象呢?步骤如下:
- 第一步:创建对象
方法: 类名 对象名 = new 类名(); // 把类实例化为一个对象
例如: Telephone phone = new Telephone();
- 第二步:使用对象
刚刚上面的例子,new后面加一个类名,再加上一个小括号,其实就相当于对一个类进行了实例化,最终得到了一个对象,只不过我们把这个对象赋给了一个对象名变量,我们对这个对象名进行操作,其实就等于对这个对象进行操作。通过对象名的点属性就可以使用对象的属性,并且给相应的属性进行赋值;另外,只需要通过对象名的点方法,就可以调用对象的方法。如下:
引用对象的属性:对象名.属性
phone.screen = 5.5;// 给screen属性赋值5
引用对象的方法:对象名.方法
phone.sendMessage(); //调用sendMessage()方法
下面是我们稍作修改后的Telephone的类,不仅有“具有发短信”这句话,而且还输出了实例变量的值。
package com.example;
//1.定义一个类
public class Telephone {
//2.属性(也叫 成员变量) ---> 代表 有什么
float screen;
float cpu;
float mem;
//3.方法 ----> 代表 干什么
void call() {
System.out.println("Telphone具有打电话的功能!");
}
void sendMessage() {
System.out.println("screen:"+ screen + "cpu:" + cpu + "mem:" + mem +"Telphone具有发短信的功能!");
}
}
当我们创建好类,怎么去实例化类的对象呢?鉴于此,我们在默认生成的Main这个类的main方法下去实例化一个Telephone对象,步骤如下:
1)先new一个对象, 即:new Telpehone();
2)然后将这个new出来的对象赋值给一个变量phone,即: phone = new Telpehone();
3)最后,这个变量类型是什么呢,我们说过,类就是实例化变量的类型,即:Telpehone phone = new Telpehone();
再接着,我们用创建好的实例化对象来调用对象的方法,即:phone.sendMessage();
完整代码整合如下:
package com.example;
public class Main {
public static void main(String[] args) {
// write your code here
Telephone phone = new Telephone(); // 对Telphone这个类进行实例化
phone.sendMessage();
}
}
我们来运行一下这个程序,结果如下:
screen:0.0cpu:0.0mem:0.0Telphone具有发短信的功能!
从上面的运行结果,我们发现这个方法执行了,但是实例变量的默认值都是0.0。
这是因为我们刚创建对象的时候,实例变量是没有值的()。
那我们通常在使用对象的时候,只做两个操作,第一个:给实例变量赋值;第二个:调用对象的方法。代码如下:
package com.example;
public class Main {
public static void main(String[] args) {
// write your code here
Telephone phone = new Telephone(); // 对Telphone这个类进行实例化
phone.sendMessage();
//给实例变量赋值
phone.screen = 5.5f;
phone.cpu = 4.0f;
phone.mem = 64.0f;
//调用对象的方法
phone.sendMessage();
}
}
那我们再来执行一下程序,结果如下:
screen:0.0cpu:0.0mem:0.0Telphone具有发短信的功能!
screen:5.5cpu:4.0mem:64.0Telphone具有发短信的功能!
1.4 Java中的成员变量和局部变量
我们在写面向对象程序的时候,主要用到两种变量:成员变量和局部变量。
- 成员变量:在类中定义,用来描述对象将要有什么
- 局部变量:在类的方法中定义,在方法中临时保存数据
成员变量和局部变量的区别:
- 局部变量的作用域仅限于定义它的方法
- 成员变量的作用域在整个类内部都是可见的
针对这一点,我们来实践一下:在Telpehone.class中定义一个成员变量: int var,然后在方法中打印这个成员变量,最后在main()方法中调用 打电话和发短信 这两个方法。
运行结果如下:
var:0
screen:5.5cpu:4.0mem:64.0Telphone具有发短信的功能!
var:0
Telphone具有打电话的功能!
从上面的运行结果,我们发现,我们定义的成员变量var可以被类中的两个方法调用,并且它的默认值为0。正如我们刚刚所说:成员变量的作用域是在整个类的内部都可以使用的,类中的所有方法共享成员变量。
我们再来看一下局部变量,首先在方法中定义一个局部变量:int localVar,如下:
- Java会给成员变量一个初始值
- Java不会给局部变量赋予初始值
- 在同一个方法中不允许有同名的局部变量
- 在不同的方法中可以有同名的局部变量
,不初始化程序会报错,报错如下:
The local variable localVar may not have been initialized
这就是为什么刚刚定义局部变量localVar的时候,我们给它赋了初始值0的原因。
我们看看运行结果如下:
1.5 Java中的构造方法
在这一节,我们看看java中如何去写一个构造方法,构造方法又帮我们解决什么问题呢?
我们之前在创建一个对象的时候说过,通过一个new关键字就可以把一个类进行实例化变成对象。其实当时来讲,这种说法并不严谨,实际上,。也就是说,
- 使用new+构造方法会创建一个新的对象
- 构造方法是定义在Java类中的一个用来初始化对象的方法
到这,我们可以了解到,构造方法也是方法,它跟一般方法的不同之处在哪里呢?一般方法只能说明对象可以干什么,而构造方法可以创建一个对象,并且可以初始化对象的值。另外,构造方法还有一个特点:构造方法与类同名且没有返回值。
1.5.1 无参构造方法
这里我们创建一个新的Java项目,项目中也创建一个Telephone.java类。创建完后,我们发现,Telephone.java类中并没有写任何方法,但是我们现在就可以使用了。在默认的Main入口类的main()方法中new一个Telephone对象,即:Telephone phone = new Telephone();
有的人就奇怪了,Telephone.java类中没有Telephone()这个方法,我们怎么还能调用呢?主要原因就是,如果我们没有指定一个无参的构造方法,系统会自动帮我们生成一个无参的构造方法,。为了证明我们执行的的确是构造方法,那么这里系统生成的这个就不需要了。在Telephone.java类中自定义一个无参的构造方法,如下:
然后,在main方法中new一个Telephone对象,如下:
我们执行一下程序,结果如下:
从执行结果,我们发现,无参的构造方法被执行了。
也就是说,。
1.5.2 有参构造方法
。也就是说,在创建对象的时候,是可以传参数的。那如何去写一个有参的构造方法呢?
Telephone.java类中定义一个有参的构造方法如下:
Main()方法中:
运行结果如下:
关于构造函数需要注意的几点:
- 当没有指定构造方法时,系统会自动添加无参的构造方法。
- 当有指定构造方法,无论是无参还是有参的构造方法,系统都不会自动添加无参的构造方法。
- 构造方法的重载:方法名相同,但参数不同的多个方法,调用时会自动根据不同的参数选择相应的方法。
- 构造方法不但可以给对象的属性赋值,还可以保证给对象的属性赋一个合理的值
针对第4点,比如对于一个手机对象,现在的智能手机的屏幕尺寸应该至少大于 3.5英寸的,如果现在传一个1.5英寸,如下:
显然这是不合理的,那么针对这样的情况,该如何处理呢?此时,就需要我们在有参构造方法中作一些逻辑判断,如下:
现在执行程序,运行结果如下:
从结果看,这样就避免了有参构造方法中传值不安全的问题。