目录
今日良言:既然选择了远方,便只顾风雨兼程
一、类和对象
1.类:
具有相同特性(属性)和行为的对象的抽象。类是一个模板
2.对象
对象是人们要进行研究的任何事物,可以表示具体的事物,还可以表示抽象的规则等。对象是实体
3.类和对象的关系
对象是根据类创建的,在java中,使用关键字new来创建一个新的对象。
对象的抽象是类,类的具体化就是对象。
4.面向对象和面向过程
举个例子:面向过程:打开冰箱,放入零食,关闭冰箱。面向对象:对于冰箱而言,打开和关闭都是对冰箱操作,是冰箱的行为。 冰箱就是一个对象,所以只要操作冰箱所具备的功能,都要定义在冰箱中。
二、类和类的实例化
类就是一类对象的统称。对象就是这一类具体化的一个实例。
举例:
1.做月饼的模子就是一个类,通过这个模子可以制作很多月饼,月饼就是对象,月饼是一个实体。
2.盖房子的图纸也是一个类,通过图纸可以盖很多房子,图纸就是类,房子就是对象,房子也是提个实体。
综上例子不难发现:一个类,可以产生无数个对象
三、类的成员
3.1字段/属性/成员变量以及方法
创建类:
class 类名{
field;//成员属性
method;//成员方法
}
1.Java中的类名采用的书写规范是大驼峰,即首字母大写,如:ArrayNumber
2.类在java中属于引用类型 ,java中使用关键字class来声明类
3.java中使用关键字new来实例化一个对象
4.类中的方法类似于C语言中的函数
class Person{
String name;//成员变量
int age;//成员变量
}
public class text {
public static void main(String[] args) {
Person person = new Person();
}
}
这里需要解释一下
Person person = new Person();
1. Person是类名,new Person() 是以Person类为模板,在堆内存空间上创建一个Person对象
2.上述代码没有构造方法,因此编译器会自动生成一个不带有参数的构造方法,后面会讲到对类的初始化:构造方法,可以更好理解
3.Person person 是创建了一个在栈空间上的对象引用person,通过“=”指向堆空间上的Person对象
4.注意:Person 是对象 person 是对象引用
如下图解:
访问修饰限定符
1.public: 公有的 只能在该类中使用 2.private 私有的 3.protected 受保护的 4.什么都不写 默认->包访问权限
3.2static关键字
3.2.1修饰属性
A.被static修饰的属性称为静态属性(静态成员变量),不被static修饰的属性称为实例属性(实例成员变量),如下
class Person{
public String name;
public int age;
public static String sex;
public static boolean flag;
}
name 和 age 是实例成员变量,sex 和 flag 是静态成员变量
需要注意:
a.静态成员变量不属于对象的引用 ,只属于类Person和实例成员变量
b.静态成员变量只有一份,存在方法区,如下图
而实例成员变量可以有多份,每new一个对象就有一份,这里运行如下图代码可以加深记忆
B.默认值规则
a.各种数字类型,默认值是0
b.对于boolean类型,默认值是false
c.对于引用类型,默认值是null
C.访问规则
对于静态成员,访问时: 类名.静态数据成员
对于实例成员,访问时:对象的引用.实例成员
如下
Person是类名 person是对象的引用
Person person = new Person();
person.age = 18;
person.name = "帅哥";
Person.sex = "男";
Person.flag = true;
3.2.2修饰方法
A.被static修饰的属性称为静态方法,不被static修饰的属性称为实例方法,如下
class Person {
public void eat() {
System.out.println("eat()!");
}
public void sleep() {
System.out.println("sleep()!");
}
public static void play(){
System.out.println("play()!");
}
}
eat 和 sleep 是实例方法, play是静态方法
需要注意:
a.静态方法属于类,而不属于对象
b.静态方法内部,不可以访问非静态的数据成员
注意:静态方法和实例方法有一些误区:参见如下文章
关于静态方法和实例方法的一些误区。 - Ivony... - 博客园 (cnblogs.com)
B.访问规则
对于静态方法,访问时: 类名.静态方法
对于实例方法,访问时:对象的引用.实例方法
如下
Person是类名 person是对象的引用
Person person = new Person(); person.eat(); person.sleep(); Person.play();
四、封装
在我们写代码的时候会涉及两种角色:类的实现者和类的调用者
封装的本质就是让类的调用者不必太多的了解实现者是如何实现类的,只要知道如何使用类即可,这样就降低了类使用者的学习和和使用成本,从而降低了复杂程度。
4.1private实现封装
被public修饰的成员变量或方法,可以被类的调用者直接使用
而private修饰的成员方法和变量,不可以被类的调用者直接使用
如下代码:使用get 和 set 方法访问私有的数据成员
class Student{
private String name;
public int age;
//提供一个公开的接口
public String getName() {
return this.name;
}
public void setName(String name){
this.name = name;
}
}
public class text{
public static void main(String[] args) {
//实例化一个对象
Student student = new Student();
student.age = 18;
student.setName("帅哥");
System.out.println(student.getName());
}
}
这里的 “this. ” 是当前对象的引用,要习惯使用this ,不理解this.没关系,我们继续往下瞧
当成员变量名和方法中的局部变量参数名相同时会发生如下情况:
public void setName(String name) {
name = name;//这里其实就是局部变量name自己给自己赋值(局部变量优先) 并没有赋值属性
}
所以这里要使用this.给成员变量name赋值 后面还有this关键字的相关知识点
public void setName(String name) {
this.name = name;
}
上述类Student中提供了一个公开的接口
public void setName(String name) {
this.name = name;
}
通过这个公开的接口可以对私有属性name进行初始化
4.2getter和setter方法
IDEA中可以使用快捷键 getter和setter方法,来直接自定义生成getName 和 setName 如下 :先定义一个类
class Student{
private String name;
public int age;
}
然后在类的内部:按住Alt+Insert,会弹出如下框(我这里是中文版)再进行操作
然后就会生成如下代码:
除了上述输出方式外,我们还可以直接调用toString输出数据,IDEA通过以下方式,首先,按住Alt+Insert ,然后选择toStrig,进入页面后,选择下图所选部分:
就会生成如下代码:然后直接输出对象的引用即可
我们这里实际上是重新实现了object类的toString方法,这里的@verride是注解,这个注解指的是这个方法是重写的。,如果不重写的话,直接打印对象的引用student会出现如下情况:
Student是类型,@后面的是地址的哈希值,
五、构造方法
5.1基本语法
构造方法实际上就是对类的初始化
构造方法的方法名和类名相同,没有返回值类型声明,如下代码:
class Person {
private String name;
public int age;
public Person() {
System.out.println("好好学习");
}
}
public class text{
public static void main(String[] args) {
Person person = new Person();
}
}
输出内容如下:
注意:
1.当没有提供构造参数时,编译器会自动生成一个不带返回值的构造参数。
2.当提供了构造参数时,编译器就不会生成构造参数,如上代码。
看到这里,可能友友们对生成对象还有迷茫,这里再详细解释一下:
一个对象的产生分成两步:
1.为对象在堆上分配内存
2.调用合适的构造方法。意味着构造方法不止一个。如下代码:
class Person {
private String name;
public int age;
public Person() {
System.out.println("好好学习");
}
public Person(String name,int age) {
this.name = name;
this.age = age;
System.out.println("天天向上");
}
}
public class text{
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person("张飞",18);
}
}
运行以后的结果如下:
不难看出,构造方法不止一个,只是构造方法“不能一模一样”,仔细观察上述代码,细心的小伙伴会发现,构造方法是支持重载的。这里补充一下方法的重载几个注意事项:
1.方法名可以相同
2.返回值不做要求
3.参数列表不同(参数的个数 或者 参数的类型不同)
4.注:一定是同一个类中
IDEA中也提供了自动生成构造方法的快捷方式:
Alt+Insert + Constructor 如下图
5.2this关键字
1.this. 代表的是当前对象的引用
那么肯定有友友会想,为什么this.代表的是当前对象的引用而不是对象呢?
因为:上面我们已经提到过了,一个对象的产生有两步,而在第二步调用合适的构造方法时,就可以使用this. 所以说:this.代表对象是不正确的,它代表的是对象的引用,指向第一步为对象分配的堆上的内存。
2.this的用法
调用当前对象的属性以及调用当前对象的方法我们已经提到过了,这里解释一下调用自己的构造方法
我们通过下面的代码段(还是上面的代码)可以更好的理解:调用自己的构造方法
class Person {
private String name;
public int age;
public Person() {
this("张飞",18);
System.out.println("好好学习");
}
public Person(String name,int age) {
this.name = name;
this.age = age;
System.out.println("天天向上");
}
}
public class text{
public static void main(String[] args) {
Person person1 = new Person();
}
}
运行结果如下图:
六、代码块
6.1认识代码块
使用{ }定义的一段代码就是代码块
6.2代码块的分类:
实例代码块
静态代码块
注:不能访问非静态的数据成员
本地代码块(不做解释)
6.3执行顺序
通过以下代码,来测试执行顺序:
class Person {
private String name;
public int age;
public Person() {
this("张飞",18);
System.out.println("好好学习");
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
{
System.out.println("实例代码块");
}
static { //不能访问非静态的数据成员
System.out.println("静态代码块");
}
}
public class text{
public static void main(String[] args) {
Person person1 = new Person();
}
}
结果如下图:
因此我们就可以总结出执行顺序:
这里我们new了一个对象,如果有两个呢?再创建一个对象的引用person2
Person person1 = new Person(); System.out.println("======================"); Person person2 = new Person();
我们再次执行代码得到的结果如下图
为什么person2中没有输出“静态代码块”呢?
因为静态的内容只会执行一次(静态方法和静态成员变量一份),且最先执行。
如果都是静态的,则谁先定义执行谁呢?
这里写一个简单的代码进行测试:
class Person {
public static int count=0;
static {
count=99;
}
}
public class text{
public static void main(String[] args) {
Person person1 = new Person();
System.out.println(Person.count);
}
}
执行结果如下图:
当交换这部分代码的定义顺序后:
public static int count=0;
static {
count=99;
}
运行结果如下:
综上可以看出:静态的内容,先定义先执行
6.4匿名对象
没有引用的对象称为匿名对象,匿名对象只能在创建对象时使用,如果一个对象只是用一次,后续不再使用,可以考虑使用匿名对象,如下图匿名对象