java第八课——类和对象


目录

一:面向对象的初步认知

1.1面向对象的定义

1.2面向对象与面向过程

1.3对象从何而来?

二:类

2.1简单认识类

2.2类的定义格式

 2.3类的实例化

三:this引用 

3.1什么是this引用

3.2this引用的特性

四:对象的构造及初始化

4.1如何初始化对象?

4.1.1就地初始化

4.1.2默认初始化 

4.2构造方法和this的梦幻联动

五:内部类

5.1内部类的定义

5.2内部类的分类

 5.3实例内部类

5.4静态内部类

5.5匿名内部类


一:面向对象的初步认知

1.1面向对象的定义

        Java是一门纯面向对象的语言,在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。

1.2面向对象与面向过程

以洗衣服为例,传统洗衣服过程为:

传统洗衣服过程

传统的方式:注重的是洗衣服的过程,少了一个环节可能都不行。
而且不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另一种方式。
按照该种方式来写代码,将来扩展或者维护起来会比较麻烦。

现代洗衣服过程为:

现代洗衣服过程

        以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,倒入洗衣粉,启动开关即可,通过对象之间的交互来完成的。 

1.3对象从何而来?

        对象是一个个具体的实例,想要有对象,先得有什么呢?

        中秋节我们总会吃月饼,这里的月饼就相当于是一个对象,那么打月饼需要什么呢?答案是月饼模具。而在面向对象中,“类”就是那个模具。

二:类

2.1简单认识类

        类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成后计算机就可以识别了。比如:

 

2.2类的定义格式

// 创建类
class ClassName{
field;       // 字段(属性) 或者 成员变量
method;      // 行为 或者 成员方法

}

        class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
        类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类具有哪些功能,称为类的成员方法。 

class WashMachine{
    public String brand; // 品牌
    public String type; // 型号
    public double weight; // 重量
    public double lenght; // 长
    public double weidth; // 宽
    public double height; // 高
    public String color; // 颜色
    public void WashClothes(){ // 洗衣服
        System.out.println("洗衣功能");
    }
    public void dryClothes(){ // 脱水
        System.out.println("脱水功能");
    }
    public void SetTime(){ // 定时
        System.out.println("定时功能");
    }
}

注意:

  1. 类名注意采用大驼峰定义;
  2. 一般一个文件当中只定义一个类;
  3.  main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法);
  4. public修饰的类必须要和文件名相同;
  5. 不要轻易去修改public修饰的类的名称。

 2.3类的实例化

        类就是一个模板,要想真的“打出月饼”,就得实例化一个对象出来。在java中采用new关键字,配合类名来实例化对象。

class PetDog{
    //狗的属性
    public String name; //名字
    public String color;//颜色
    //狗的行为

    public void barks(){
        System.out.println(name+"在旺旺旺~~~");
    }
    public void wag(){
        System.out.println(name+"在摇尾巴~~~");
    }
}

public class Test1 {
    public static void main(String[] args) {
        PetDog dogh = new PetDog(); //通过new实例化对象
        dogh.name = "哈尼";
        dogh.color = "黑黄";
        dogh.barks();
        dogh.wag();
        PetDog dogs = new PetDog();
        dogs.name = "小乖";
        dogs.color = "白色";
        dogs.barks();
        dogs.wag();
    }
}

 运行结果如下:

注意:

  1. new 关键字用于创建一个对象的实例;
  2. 使用 . 来访问对象中的属性和方法;
  3. 同一个类可以创建多个实例,实例化出的对象占用实际的物理空间,存储类成员变量;
  4. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员;
  5. 类是一种自定义的类型,可以用来定义变量,在java中用类定义出来的变量,我们称为对象;
  6. 打个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。

三:this引用 

3.1什么是this引用

        java编译器给每个“成员方法“增加了一个隐藏的引用类型参数,该引用参数指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

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);
    }

    public static void main(String[] args) {
        // 构造三个日期类型的对象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
        // 对d1,d2,d3的日期设置
        d1.setDay(2021,9,15);
        d2.setDay(2021,9,16);
        d3.setDay(2021,9,17);
        // 打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

运行结果如下:

 注意:this引用的是调用成员方法的对象。图解如下:

3.2this引用的特性

1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型;
2. this只能在"成员方法"中使用;
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象,具有final属性;
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责调用成员方法;
5.对象的引用传递给该成员方法,this负责来接收。

建议:在书写代码时,习惯使用this。

四:对象的构造及初始化

4.1如何初始化对象?

4.1.1就地初始化

        在创建类成员时,就地进行初始化的操作。例如:

class Player {
    public String name="勒布朗詹姆斯";
    public int age=37;
    public double score=99;
    public String sex="男";
}

4.1.2默认初始化 

        当我们实例化一个对象的时候,至少会有这两步:

        1.为对象分配内存;

        2.调用合适的构造方法; 

        而使用构造方法进行初始化的操作,我们称之为默认初始化。

什么是构造方法? 

        构造方法,是一种特殊的方法,它是一个与类同名的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载

 具体实例如下:

class Player {

    public String name;
    public int height;
    public double score;
    public String team;

    public Player() {
        System.out.println("这个是不带参数的构造方法!");
    }

    public Player(String name,int height) {
        this.height = height;
        this.name = name;
        System.out.println("这个是带2个参数的构造方法!");
    }

    public Player(String name, int height, double score, String team) {
        this.name = name;
        this.height =height;
        this.score = score;
        this.team = team;
        System.out.println("这个是带4个参数的构造方法!");
    }

    public void joinMatch() {
        System.out.println(name+"正在比赛!");
    }
    public void getScore(){
        System.out.println(name+"正在得分!");
    }

    public void show() {
        System.out.println("姓名:"+name+" 身高:"+height+" 单场得分"+score+" 所属球队:"+team);
    }
}
public class Test2{
    public static void main(String[] args) {
        Player player1 = new Player();//球员 对象/实体
        player1.show();
        System.out.println("------------------------------");
        Player player2 = new Player("科比布莱恩特",198);//球员 对象/实体
        player2.score=81;
        player2.team="湖人";
        player2.show();
        System.out.println("------------------------------");
        Player player3 = new Player("阿伦艾弗森",183,65,"76人");//球员 对象/实体
        player3.show();
        player3.joinMatch();
        player3.getScore();
    }
}

运行结果如下:

从这个例子中,我们需要知道以下几点:

1.仅使用不带参数的构造方法,那么该对象的所有成员变量会被赋予一个初始值。

2.构造方法不止一个,可以有多个,多个构造方法之间,构成了重载。

3.构造方法是没有返回值的方法,方法名和类名是一样的。

4.当我们写了一个类之后,没有写构造方法的时候,编译器会帮我们默认生成一个不带参数的构造方法 ; 当我们写了任何一个构造方法之后,编译器不再为我们提供不带参数的构造方法。

5.一个类至少会有1个构造方法,就算你没有写!!!

技巧:如何再IDEA中迅速添加构造方法?

1.在任意空白行右击鼠标;

2.选择Generate;

 3.选择Constructor;

 4.选择你要添加的构造方法的参数个数;

5.成功添加!

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

4.2构造方法和this的梦幻联动

        this可以用来调用本类中其他的构造方法【构造方法当中使用】。必须放到第一行!!!所以,只能在当前构造方法当中,调用一个。具体实例如下:

class Player {

    public String name;
    public int height;
    public double score;
    public String team;

    public Player() {
        this("迈克尔乔丹",198,69,"公牛");
        System.out.println("这个是不带参数的构造方法!");
    }


    public Player(String name, int height, double score, String team) {
        this.name = name;
        this.height =height;
        this.score = score;
        this.team = team;
        System.out.println("这个是带4个参数的构造方法!");
    }

    public void show() {
        System.out.println("姓名:"+name+" 身高:"+height+" 单场得分"+score+" 所属球队:"+team);
    }
}
public class Test2{
    public static void main(String[] args) {
        Player player1 = new Player();//球员 对象/实体
        player1.show();
    }
}

运行结果如下:

 注意它们的执行顺序!

this 的用法:

a.this.data;         访问属性
b. this.func();      访问方法
c. this();              调用本类中其他的构造方法

注意:this不能形成环。

 如果出现这种情况,就会发生递归构造器调用,导致死循环,所以this不能形成环。

五:内部类

5.1内部类的定义

        当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

5.2内部类的分类

 5.3实例内部类

Q1:如何实例化内部类对象?

A:外部类名.内部类名 变量 = 外部类对象的引用.new 内部类名();

具体实例如下:

package Test;

class OuterClass {
    //普通成员变量 / 实例成员变量
    public int data1 = 10;

    class InnerClass {
        public int data2 = 20;
    }
}


public class TestDemo1 {

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        //外部类名.内部类名  变量 =  外部类对象的引用.new 内部类名();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    }

}

Q:实例内部类当中可以定义静态的成员变量吗?

A:理论上不可以。如果要定义,必须是编译的时候确定的值(即必须是static final的)。例如:
public static final int data6 = 60; 编译的时候就确定了这个值是多少了。

Q:实例内部类当中,如果有成员变量和外部类的成员变量重名了?怎么办?

A:首先,优先访问自己的;如果要访问外部类的,用外部类.this.成员变量名。

package Test;

class OuterClass {
    //普通成员变量 / 实例成员变量
    public int data1 = 10;
    private int data2 = 20;
    public static int data3 = 30;

    class InnerClass {
        public int data1 = 100;
        public int data4 = 40;
        private int data5 = 50;
        public static final int data6 = 60;


        public void method() {
            System.out.println("访问外部类的——>" + OuterClass.this.data1);
            System.out.println("访问自己的——>" + this.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
            System.out.println("InnerClass的一个method方法!");
        }
    }

}


public class TestDemo1 {

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        System.out.println("======================");
        //外部类名.内部类名  变量 =  外部类对象的引用.new 内部类名();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.method();
    }

}

运行结果如下:

 结论:实例内部类中不仅包含了自己的this ,而且包含了外部类的this。

Q:可以包含静态方法吗?

A:不可以!

总结:
1. 外部类中的任何成员都可以被在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名.this.同名成员 来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问内部类中的成员,如果要访问必须先要创建内部类的对象。 

5.4静态内部类

Q:如何实例化静态内部类?

A:外部类名.内部类名 变量  = new 外部类名.内部类名();

        与实例内部类相比,静态内部类在使用时不依赖于外部类对象。从这一角度而言,静态内部类使用频率较高。

Q:静态内部类当中,是否可以访问到外部类的所有成员?

A:不,只能访问到外部类的静态的成员。

Q:如果要访问外部类的非静态成员,那么怎么访问?

A:提供外部类对象。

package Test;


class OuterClass2 {

    public int data1 = 10;
    private int data2 = 20;
    public static int data3 = 30;

    public void method() {
        System.out.println("OuterClass2::method()");
    }


    static class InnerClass {
        public int data4 = 40;
        private int data5 = 50;
        public static int data6 = 60;

        OuterClass2 out = new OuterClass2();

        public void method() {
            System.out.println(out.data1);
            System.out.println(out.data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}

public class TestDemo2 {
    //不需要外部类对象  所以 静态内部类使用的频率会比较多
    public static void main(String[] args) {
        OuterClass2.InnerClass innerClass = new OuterClass2.InnerClass();
        innerClass.method();
    }
}

运行结果如下:

 在这里我会补充一点,即对于内存的分配:

        记得我们在前面的文章中谈到过,引用不一定在栈上,还有可能在堆上,这就是一个很好的例子。

5.5匿名内部类

        在后续讲“接口”的文章中会详细论述到。


本课内容结束! 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值