Java学习——第N次学习面向对象

第N次学习面向对象,希望是最后一次。。

类和对象

所谓类,就是对一类事物的描述,是抽象的、概念上的定义,比如鸟类,就泛指所有具有鸟类特征的动物。比如人类,不同的人,有着不同的性格、不同的爱好、不同的样貌等等,但是他们根本上都是人,所以说可以将他们抽象描述为人类。

对象是某一类事物实际存在的每个个体,因而也被称为实例(instance)我们每个人都是人类的一个实际存在的个体。

类的定义与对象的创建

定义类时,应该用英文单词,并且首字母大写,不能出现任何的特殊字符。

创建一个Person类:

1
2
3
4
5
6
public class Person{ //这里定义的人类具有三个属性,名字、年龄、性别
//直接在类中定义变量,表示类具有的属性
String name;
int age;
String sex;
}

类创建完成之后,可以创建一个实例对象,实例对象对应的是一个具体的人:

1
new 类名();
1
2
3
4
public static void main{
new Person(); //我们可以使用new关键字来创建某个类的对象,注意new后面需要跟上 类名()
//这里创建出来的,就是一个具体的人了(实体)
}

整个流程:

流程这里仅仅是创建出一个对象,并没有办法操作这个对象,如修改姓名等等。

对象的使用

访问这个对象,可以使用一个变量来指代某个对象,但是引用类型的变量,存储的是对象的引用,而不是对象的本身。

1
2
3
4
5
6
7
public static void main(String[] args) {
//这里的a存放的是具体的某个值
int a = 10;
//创建一个变量指代我们刚刚创建好的对象,变量的类型就是对应的类名
//这里的p存放的是对象的引用,而不是本体,我们可以通过对象的引用来间接操作对象
Person p = new Person();
}

至于为什么对象类型的变量存放的是对象的引用,比如:

1
2
3
4
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = p1;
}

这里,我们将变量p2赋值为p1的值,那么实际上只是传递了对象的引用,而不是对象本身的复制,这跟我们前面的基本数据类型有些不同,p2和p1都指向的是同一个对象(类似于指针一样的存在)

类使用的都是引用类型。

现在我们有了对象的引用之后,我们就可以进行操作了:

我们可以直接访问对象的一些属性,也就是我们在类中定义好的那些,对于不同的对象,这些属性都具体存放值也会不同

比如我们可以修改对象的名字:

1
2
3
4
5
public static void main(String[] args) {
Person p = new Person();
p.name = "小明"; //要访问对象的属性,我们需要使用 . 运算符
System.out.println(p.name); //直接打印对象的名字,就是我们刚刚修改好的结果了
}

不同对象的属性是分开独立存放的,每个对象都有一个自己的空间,修改一个对象的属性并不会影响到其他对象

1
2
3
4
5
6
7
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
p1.name = "小明"; //这个修改的是第一个对象的属性
p2.name = "大明"; //这里修改的是第二个对象的属性
System.out.println(p1.name); //这里我们获取的是第一个对象的属性
}

关于对象类型的变量,我们也不可以对任何对象进行引用:

1
2
3
4
5
public static void main(String[] args) {
Person p1 = null; //null是一个特殊的值,它表示空,也就是不引用任何的对象
p.name = "小红"; //我任性,就是要操作
System.out.println(p.name);
}

注意,如果不引用任何的对象,那肯定是不应该去通过这个变量去操作所引用的对象的(都没有引用对象,我操作谁啊我)

虽然编译时可以编译,但是在运行时会抛出空指针异常。

创建对象后,如果直接访问的运行结果:

1
2
3
4
5
6
public static void main(String[] args) {
Person p = new Person();
System.out.println("name = "+p.name);
System.out.println("age = "+p.age);
System.out.println("sex = "+p.sex);
}

我们可以看到,如果直接创建对象,那么对象的属性都会存在初始值,如果是基本类型,那么默认是统一为0(如果是boolean的话,默认值为false)如果是引用类型,那么默认是null

方法的创建和使用

前面我们的类有了属性,我们可以为这些类创建不同的属性值,如每个人的名字不一样,年龄不一样等等,但是光有属性是不够的,需要具有一定的行为,如人可以行走跳跃,可以思考等等。

对象做出的行为,这就是方法。

方法是为了完成某件事而存在的,完成某件事,可以有结果,也可以没有结果。所以有的方法有返回值,有的方法没有返回值。

方法的定义:

1
2
3
返回值类型 方法名称() {
方法体...
}

首先是返回值类型,也就是说这个方法完成任务之后,得到的结果的数据类型(可以是基本类型,也可以是引用类型)当然,如果没有返回值,只是完成任务,那么可以使用void表示没有返回值,比如我们现在给人类编写一个自我介绍的行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Person {
String name;
int age;
String sex;

//自我介绍只需要完成就行,没有返回值,所以说使用void
void hello(){
//完成自我介绍需要执行的所有代码就在这个花括号中编写
//这里编写代码跟我们之前在main中是一样的(实际上main就是一个函数)
//自我介绍需要用到当前对象的名字和年龄,我们直接使用成员变量即可,变量的值就是当前对象的存放值
System.out.println("我叫 "+name+" 今年 "+age+" 岁了!");
}
}

注意,方法名称同样可以随便起,但是规则跟变量的命名差不多,也是尽量使用小写字母开头的单词,如果是多个单词,一般使用驼峰命名法最规范。

我们定义好方法之后,如何让对象执行这个行为?

1
2
3
4
5
6
public static void main(String[] args) {
Person p = new Person();
p.name = "小明";
p.age = 18;
p.hello(); //我们只需要使用 . 运算符,就可以执行定义好的方法了,只需要 .方法名称() 即可
}

这样执行定义好的方法,我们称之为方法的调用,运行后的效果如下:

1
我叫 小明 今年 18 岁了!

比如现在我们要让人类学会加法运算,我们也可以通过定义一个方法的形式来完成,只不过,要完成加法运算,我们需要别人给人类提供两个参与加法运算的值才可以,所以我们这里就要用到参数了:

1
2
3
4
5
6
7
8
//我们的方法需要别人提供参与运算的值才可以
//我们可以为方法设定参数,在调用方法时,需要外部传入参数才可以
//参数的定义需要在小括号内部编写,类似于变量定义,需要填写 类型和参数名称,多个参数用逗号隔开
int sum(int a, int b){ //这里需要两个int类型的参数进行计算
int c = a + b; //直接c = a + b
return c; //return后面紧跟需要返回的结果,这样就可以将计算结果丢出去了
//带返回值的方法,是一定要有一个返回结果的!否则无法通过编译!
}

关于return关键字:

在我们使用return关键字之后,方法就会直接结束并返回结果,所以说在这之后编写的任何代码,都是不可到达的:

return后编写代码,会导致编译不通过,因为存在不可达语句。

如果我们的程序中出现了分支语句,那么必须保证每一个分支都有返回值才可以:

只要有任何一个分支缺少了return语句,都无法正常通过编译,总之就是必须考虑到所有的情况,任何情况下都必须要有返回值。

当然,如果方法没有返回值,我们也可以使用return语句,不需要跟上任何内容,只不过这种情况下使用,仅仅是为了快速结束方法的执行:

1
2
3
4
void test(int a){
if(a == 10) return; //当a等于10时直接结束方法,后面无论有没有代码都不会执行了
System.out.println("Hello World!"); //不是的情况就正常执行
}