Java学习DAY8~类和对象(一)~2021.01.17

1. 类和对象

1.1 简单认识类

  • 类主要是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些工功能(用用来干啥),描述完成后告诉给计算机的。
  • 比如,洗衣机就是一个实体或者称为对象。但是计算机不认识洗衣机,如果要让计算机认识洗衣机,在java中必须通过类对计算机进行描述。
  • 洗衣机类:
    属性:生产厂商,品牌,出厂日期,大小尺寸,颜色…
    功能:电源开关,暂时/开始,洗衣,烘干…

1.2 类的定义格式

在java中定义类时需要用到class关键字,具体语法如下

// 创建类
class ClassName{
field;//成员属性
method;//成员方法
}
  • class为定义类的关键字,ClassName为类的名字,{ }中为类的主体。
    类中包含的内容称为类的成员。
  • 变量信息主要是对类进行描述的,称之为类的成员属性或者类成员变量。
  • 方法主要说明类具有哪些功能,称为类的成员方法。

1.3 尝试定义一个类

class Cat {
public String name;//名字
public int age;//年龄
public String color;//颜色
public double weight;//体重
public String gender;//性别
//猫的行为,既方法
public void barks() {
System.out.println("mewing,mewing");
}
public void jump() {
System.out.println("jump,jump");
}
}

2. 类的实例化

2.1 什么是实例化

  • 定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:Cat类和Computer类。有了这些自定义的类之后,就可以使用这些类来定义实例(或者称为对象)。
  • 用类类型创建对象的过程,称为类的实例化,在java中才用new关键字,配合类名来实例化对象。
class Person {
public int age;//成员属性 实例变量
public String name;
public String sex;
public void eat() {//成员方法
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person();//通过new实例化对象
person.eat();//成员方法调用需要通过对象的引用调用
person.sleep();
//产生对象 实例化对象
Person person2 = new Person();
Person person3 = new Person();
}
}

输出结果为:

吃饭!
睡觉!
  • 注意事项
  1. new 关键字用于创建一个对象的实例.
  2. 使用 . 来访问对象中的属性和方法.
  3. 同一个类可以创建对个实例.

2.2 类和对象的说明

  • 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
  • 类是一种自定义的类型,可以用来定义变量,但是在java中用类定义出来的变量我们成为对象.
  • 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  • 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

2.3 常见定义类语法错误

  • 同一个类当中,定义的类,不能和public修饰的类,名称相同
class TestDemo {
}
public class TestDemo {
public static void main(String[] args) {
System.out.println("hello");
}
}

此时会发生编译错误:TestDemo.java:4: 错误: 类重复: TestDemo

3. 类的成员

3.1 字段/属性/成员变量

在类中, 但是方法外部定义的变量. 这样的变量我们称为 “字段” 或 “属性” 或 “成员变量”(三种称呼都可以,一般不会严格区分).

  • 字段就地初始化
    很多时候我们不希望字段使用默认值, 而是需要我们显式设定初值. 可以这样写:
class Person {
public String name = "张三";
public int age = 18;
}
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
System.out.println(person.age);
}
}

// 执行结果

张三
18

3.2 成员变量的默认值

  • 如果针对对象中的成员没有显式的进行初始化,此时也是存在一个默认值的
  • 默认值的规则:
  1. 数字类型(包括整数和浮点数)默认初始化为0
  2. 布尔类型,默认初始化为 false
  3. 引用类型,默认初始化为 null
  4. 在Java 中创建一个对象,它的成员变量往往并不是要初始化为 0 这类的值,但是由于Java中有这种默认规则,创建一个对象出来之后,会先把所有成员初始化为 0 值,然后在通过其他的初始化手段(例如构造方法)进一步的初始化成其他值。

3.3 方法 (method)

  • 用于描述一个对象的行为.
class Person {
public int age = 18;
public String name = "张三";
public void show() {
System.out.println("我叫" + name + ", 今年" + age + "岁");
}
}
class Test {
public static void main(String[] args) {
Person person = new Person();
person.show();
}
}

// 执行结果

我叫张三, 今年18
  • 此处的 show 方法, 表示 Person 这个对象具有一个 “展示自我” 的行为.
    这样的 show 方法是和 person 实例相关联的. 如果创建了其他实例, 那么 show 的行为就会发生变化。
Person person2 = new Person();
person2.name = "李四";
person2.age = 20;
person2.show()
// 执行结果
我叫李四, 今年20

3.4 构造方法 (construction method)

  • 构造方法是类中的一组特殊的方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作.
  • new 执行过程
    为对象分配内存空间
    调用对象的构造方法
  • 语法规则
  1. 方法名称必须与类名称相同
  2. 构造方法没有返回值类型声明
  3. 每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
  • 注意事项
  1. 如果类中没有提供任何的构造函数,那么编译器会默认生成一个不带有参数的构造函数
  2. 若类中定义了构造方法,则默认的无参构造将不再生成.
  3. 构造方法支持重载. 规则和普通方法的重载一致.
  • 构造方法的特点:
  1. 构造方法名和类名一致;
  2. 构造方法不需要写返回值类型,内部也不必写 return 语句;
  3. 构造方法不需要显示调用,new 的时候自动被调用;
  4. 构造方法支持重载,可以有多个构造方法,不同的构造方法所支持的参数或者个数或者类型的不同的;
  5. 可以借用 idea 的快捷键快速生成构造方法 alt + insert ;
  6. 使用构造方法,最主要的用途也就是针对成员进行初始化。
  • 虽然我们前面已经能将属性就地初始化, 但是有些时候可能需要进行一些更复杂的初始化逻辑, 那么就可以使用构造方法.
  • 代码示例
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
name = "caocao";
age = 10;
sex = "男";
}
//带有3个参数的构造函数
public Person(String myName,int myAge,String mySex) {
name = myName;
age = myAge;
sex = mySex;
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//调用不带参数的构造函数 如果程序没有提供会调用不带参数
的构造函数
p1.show();
Person p2 = new Person("zhangfei",80,"男");//调用带有3个参数的构造函数
p2.show();
}
}
// 执行结果
name: caocao age: 10 sex: 男
name: zhangfei age: 80 sex:

3.5 static 关键字

如果一个成员每一被 static 修饰,这是一个对象的 属性/成员/字段。
如果一个成员被 static 修饰了,这就是这个类的 属性/成员/字段。

  • a) 修饰属性,Java静态属性和类相关, 和具体的实例无关. 换句话说, 同一个类的不同实例共用同一个静态属性.
class TestDemo{
public int a;
public static int count;
}
public class Main{
public static void main(String[] args) {
TestDemo t1 = new TestDemo();
t1.a++;
TestDemo.count++;
System.out.println(t1.a);
System.out.println(TestDemo.count);
System.out.println("============");
TestDemo t2 = new TestDemo();
t2.a++;
TestDemo.count++;
System.out.println(t2.a);
System.out.println(TestDemo.count);
}
}

输出结果为:

1
1
============
1
2

代码内存解析:count被static所修饰,所有类共享。且不属于对象,访问方式为:类名 . 属性。

  • b) 修饰方法
    如果在任何方法上应用static 关键字,此方法称为静态方法。
    静态方法属于类,而不属于类的对象。
    可以直接调用静态方法,而无需创建类的实例。
    静态方法可以访问静态数据成员,并可以更改静态数据成员的值。
class TestDemo{
public int a;
public static int count;
public static void change() {
count = 100;
//a = 10; error 不可以访问非静态数据成员
}
}
public class Main{
public static void main(String[] args) {
TestDemo.change()//无需创建实例对象 就可以调用
System.out.println(TestDemo.count);
}
}

输出结果

100
  • 注意事项1: 静态方法和实例无关, 而是和类相关. 因此这导致了两个情况:
    静态方法不能直接使用非静态数据成员或调用非静态方法(非静态数据成员和方法都是和实例相关的).
    this和super两个关键字不能在静态上下文中使用(this 是当前实例的引用, super是当前实例父类实例的引用, 也是和当前实例相关).
  • 注意事项2
    我们曾经写的方法为了简单, 都统一加上了 static. 但实际上一个方法具体要不要带 static, 都需要视情形而定.
    main 方法为 static 方法.

4. this指针

4.1 什么是 this 引用

  • this 就相当于代词“我” 。this 具体对应的是哪个对象,就看当前的方法,是通过哪个对象调用的。
  • 换个角度理解 this ,每个成员方法都默认带了一个额外的参数, this 就是这个额外的参数。
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year + "/" + this.month + "/" + this.day);
}
}

4.2 this 引用的特性

  1. this引用的类型:对应类类型引用,即那个对象调用就是那个对象的引用类型
  2. this引用只能在"成员方法中使用"
  3. this引用具有final属性,在一个成员方法中,不能再去引用其他的对象
  4. this引用是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将
    调用成员方法对象的引用传递给该成员方法,this引用负责来接收
  5. 在成员函数中,所有成员变量的访问,都会被编译器修改成通过this来访问

4.2.1 通过this调用类中的属性

class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
this.name = "caocao";
this.age = 10;
this.sex = "男";
}
//带有3个参数的构造函数 注意此时形参的命名和属性的命名一样
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show(){
System.out.println("name: "+this.name+" age: "+this.age+" sex:
"+this.sex);
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//调用不带参数的构造函数 如果程序没有提供会调用不带参数
的构造函数
p1.show();
Person p2 = new Person("zhangfei",80,"男");//调用带有3个参数的构造函数
p2.show();
}
}
// 执行结果
name: caocao age: 10 sex: 男
name: zhangfei age: 80 sex:class Person

4.2.2 通过this调用类中的方法

class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
this.name = "caocao";
this.age = 10;
this.sex = "男";
}
//带有3个参数的构造函数 注意此时形参的命名和属性的命名一样
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void eat() {
System.out.println(this.name+" 正在吃饭!");
}
public void show(){
System.out.println("name: "+this.name+" age: "+this.age+" sex:
"+this.sex);
//在show方法当中,通过this引用来调用本类的eat方法
this.eat();
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//调用不带参数的构造函数 如果程序没有提供会调用不带参数
的构造函数
p1.show();
Person p2 = new Person("zhangfei",80,"男");//调用带有3个参数的构造函数
p2.show();
}
}
//执行结果
name: caocao age: 10 sex: 男
caocao 正在吃饭!
name: zhangfei age: 80 sex: 男
zhangfei 正在吃饭!

4.2.3 通过this调用自身的构造方法

class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
//this调用构造函数
this("bit", 12, "man");//必须放在第一行进行显示
}
//这两个构造函数之间的关系为重载。
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show() {
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person();//调用不带参数的构造函数
person.show();
}
}
// 执行结果
name: bit age: 12 sex: man
  • 我们会发现在构造函数的内部,我们可以使用this关键字,构造函数是用来构造对象的,对象还没有构造好,我们就使用了this,那this还代表当前对象吗?当然不是,this代表的是当前对象的引用。
  • 注意事项总结:
  • 场景:需要在一个构造方法当中,调用当前类的另外一个构造方法的时候,通过this()的形式调用。
  • 必须放在第一行,且只能调用一个
public Person() {
this("caocao",12);
//this("wukong",500,"man"); 此时程序编译错误,当前类只能调用1个构造方法
}
//带有3个参数的构造函数
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//带有2个参数的构造函数
public Person(String name,int age ) {
this.name = name;
this.age = age;
}
  • 使用this调用构造方法的时候,只能在构造函数当中使用,不能再普通方法当中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值