Java类和对象

一、认识面向对象

1.1面向对象和面向过程

面向过程:面向过程即强调过程,比如说我们要做一个大型的项目,我们就把该项目划分为几个功能块(函数),把这几个功能块组合在一起就形成了一个项目,我们重点关注就是这几个函数(方法)。重点强调的就是每一个方法,每一个过程。
面向对象:面向对象即强调对象,比如我们要做一个大型的项目,我们换一种思想,我们找一个对象,该对象具备这几个功能,重点关注的是对象。
面向对象和面向过程的关系:面向对象是基于面向过程的,是建立在面向过程基础之上的。
举例:
面向过程:当我们去旅游的时候,我们需要亲自买机票、车票、门票等等。
面向对象:找一家旅游公司,只需要交钱、他就会帮你全部办好,使我们出行变得更方便了。
面向对象的好处:

  • 它是一种更符号我们人类思想习惯的思想
  • 可以将复杂的事情简单化

1.2什么是面向对象(Object Oriented)

面向对象是软件开发的一种思想,一种编程风格,面向对象开发方法认为客观世界是由对象组成的, 对象属性行为组成。任何对象都可以看做某 一类事物的实例,面向对象的方法主要是把事物给对象化(实例化)。
一类事物:人类、狗类、树类……
对象:一个人、一只狗,一棵树……
属性:人的属性有身高、年龄、姓名、性别……
行为:人会吃、喝、玩、乐……

二、类定义和使用

2.1认识类

类是对现实生活中一类具有共同特征的事物的抽象,描述 一类对象对象的属性和行为。
举例:人类
世界上所有的人统称为人类,人类具有很多的属性和行为,我们每一个个体都是一个对象,不同对象的属性和行为都有所差异。
在Java语言中,是如何定义类的?

2.2类的定义格式

在Java中定义类使用class关键字,定义格式如下👇

class 类名{
	field//属性(成员变量或字段)
	method//行为(成员方法)
}
class Human{
	public String name;
	public int age;
	public String sex;
	
	public void eat(){
		System.out.println(name+":吃东西");//谁吃东西
	}
	public void sleep(){
		System.out.println(name+":睡觉");//谁睡觉
	}
}

2.3类的实例化

相当于在计算机中定义了一种新的类型,与Java中的基本类型类似,类是自定义的新类型,我们可以通过这些类,实例出对象,称为类的实例化。
在java中采用new关键字配合类名来实例化对象。
类的定义

public class Demo {
    public static void main(String[] args) {
        Human person1 = new Human();
        person1.name = "Abel";
        person1.eat();
        Human person2 = new Human();
        person2.name = "Anli";
        person2.eat();
        Human person3 = new Human();
        person3.name = "Kari";
        person3.eat();
    }
}

运行结果

注意事项:

  • new关键字用于创建一个对象的实例
  • 使用.访问对象中的属性和方法
  • 一个类可以创建多个实例

2.4类和对象的说明

类就相当于我们设计房子时的一张图纸,只设计出了一些东西,并没有实际的建筑存在,类的实例化相当于使用设计图建造出房子。

  1. 类相对于模型,可以对一个实体进行描述。
  2. 类是一种自定类型,可以用来定义变量。
  3. 一个类可以实例化多个对象,实例化的每一个对象占用实际的物理空间,存储类的成员变量

在这里插入图片描述

三、this引用

3.1为什么要this引用

当我们在类中定义的成员变量和成员方法时一般不立即具体化,而是当实例化才开始调用和赋值,
案例引入:日期类

public class Test {
    public static void main(String[] args) {
        Data data = new Data();
        data.setDate(2022,5,20);
        data.printData();
    }
}
class Data{
    public int year;
    public int month;
    public int day;
    
    public void setDate(int year, int month, int day){
        year = year;
        month = month;
        day = day;
    }

    public void printData(){
        System.out.println(year+"/"+month+"/"+day);
    }
}

结果并不是我们想要的!!!
1.形参名和成员变量名相同?

    public void setDate(int year, int month, int day){
        year = year;
        month = month;
        day = day;
    }

到底是谁给谁赋值呢?成员变量给成员变量?参数给参数?参数给成员变量?成员变量给参数?
在这里插入图片描述
可以看出,是参数给了参数!!那么该如何解决呢?

3.2什么是this引用

this引用指向当前对象,哪个对象调用this所在的方法,this就代表哪个对象,可见this的灵活性。
在这里插入图片描述

this引用的特性

  • 哪个对象调用就是哪个对象的类型
  • this只能在非静态成员方法和构造方法中使用

四、对象的构造及初始化

上文我们使用一个方法给对象初始化, 每次需要调用方法初始化,比较繁琐,那么该如何解决呢?

4.1构造方法

构造方法(构造器),是一种特殊的方法,它是一个与类同名的方法,对象的创建就是通过构造方法来完成的,其功能主要完成对象的初始化,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        Data data1 = new Data(2022,5,20);
        data1.printData();
        Data data2 = new Data(2022,5,21);
        data2.printData();
        Data data3 = new Data(2022,5,22);
        data3.printData();
    }
}
class Data{
    public int year;
    public int month;
    public int day;

	//构造方法一般情况下用public修饰
    public Data(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
	public Data(){
		//无参构造方法
	}
    public void printData(){
        System.out.println(this.year+"/"+this.month+"/"+this.day);

    }
}

构造方法的特性:

  • 名字必须与类名相同
  • 没有返回值类型
  • 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  • 构造方法也可以重载

在这里插入图片描述

  • 若用户未定义构造方法,编译器会默认生成一个不带参的构造方法,若用户有定义,编译器则不再生成

在这里插入图片描述

4.2构造方法和this

构造方法中,可用通过this调用其他构造方法来简化代码

class Data{
    public int year;
    public int month;
    public int day;

    public Data(int year, int month, int day){
        this(year,month);
        this.day  = day;
    }
    
    public Data(int year, int month){
        this.year = year;
        this.month = month;
    }

    public void printData(){
        System.out.println(this.year+"/"+this.month+"/"+this.day);
    }
}

注意:

  • this(…)必须是构造方法中的第一条语句
  • 不能形成环

总结:

  • this.成员变量(引用this指向对象的成员变量)
  • this(参数列表)调用其他构造方法
  • this.成员方法(引用this指向对象的成员方法)

4.3初始化

一个局部变量未初始化,是不能够被使用的,而成员变量可以不初始化就可以使用。
成员变量默认初始化:

数据类型默认值
byte0
char‘\u0000’
short0
int0
long0L
float0.0f
double0.0
booleanfalse
referencenull
成员变量就地初识化
在定义变量时,就直接给初值
class Person{
    String name = "maria";
    int age  = 10;
}

注意:代码编译完成后,编译器会将所有的初始化语句添加到各个构造方法中。

五、代码块

在这里插入图片描述

5.1普通代码块

public static void main(String[] args){
	//直接使用{}定义,没有什么特殊的作用,比较少见
	{
		int x = 10;
		System.out.println(a);
	}
}

5.2构造代码块

构造代码块一般用于初始化实例成员变量。
在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.show();
    }
}

在这里插入图片描述
因为构造代码块是独立的,当我们创建对象时,如果构造代码块和构造方法同时存在时,先执行构造代码块,再执行构造方法。
注意:构造代码块,只要创建一个对象就会执行一次
用途:一般用于初始化实例成员变量

5.3静态代码块

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.show();
        Student student2 = new Student();
        student2.show();
    }
}

在这里插入图片描述
静态代码块,用static声明,JVM加载类时执行,所以执行顺序比实例代码块早。
用途:一般用来初始化静态成员变量
注意事项:

  • 静态代码块不管类实例化了多少个对象,都只会执行一次
  • 如果一个类中包含个静态代码块,再编译代码时,编译器会按照定义的先后顺序依次合并

六、内部类

内部类:一个类定义在另一个类或者一个方法的内部。
在这里插入图片描述

6.1实例内部类

定义在类中的类,定义位置与类成员所处的位置相同,也称为成员内部类。
在这里插入图片描述

class Demo1{
    public static void main(String[] args) {
        //创建实例内部类对象方法
        //1.外部类名.内部类名  变量名 = new 外部类名().new 内部类名()
        OuterClass.InnerClass innerClass1 = new OuterClass().new InnerClass();

        //2.先创建外部类对象,在创建内部类对象
        OutClass outClass1 = new OutClass();
        OutClass.InnerClass innerClass2 = outClass1.new InnerClass();
    }
}

总结:

  1. 外部类的任何成员都可以在实例内部类中访问。
  2. 实例内部类,也受访问限定符的约束。
  3. 在实例内部类与外部类成员同名,使用同名的成员时,优先访问自己的,如果要访问外部类同名的成员,外部类名.this.同名成员来访问。
  4. 实例内部类对象必须先有外部类对象的前提下才能创建。
  5. 外部类中,不能直接访问实例内部类的成员,要访问必须要创建内部类对象。
  6. 实例内部类不能有静态的成员方法和成员变量。

6.2静态内部类

使用static修饰的成员内部类
在这里插入图片描述

public class Demo {
    public static void main(String[] args) {
        //1.不需要创建外部类对象即可创建内部类
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
        innerClass.print();
    }
}

总结:

  1. 静态内部类只能访问外部类中的静态成员
  2. 创建外部类对象时,不需要创建外部类对象

6.3局部内部类

定义在方法体或者{}中。
在这里插入图片描述

public class Demo {
    public static void main(String[] args) {
        //编译报错
        OutClass.InnerClass innerClass = new OutClass().new InnerClass();
    }
}

总结:

  1. 局部内部类只能在所定义的方法体内部使用
  2. 只能在方法内部,不存在外部可见性问题,因此不能用访问权限符修饰,static也不能修饰。
  3. 编译器也会未该类生成独立的字节码文件
  4. 可以访问外部类的成员变量
  5. 可以使用final或abstract修饰

6.3匿名内部类

没有名字的局部内部类
为什么要使用匿名内部类?
是Java为了方便我们编写程序而设计的一个机制,往往我们在开发会遇到这样一个情况,一个接口/类的方法只要用到一次,但我们如果要去使用它,我们需要创建它的实现类/子类去实现重写,使用匿名内部类就可以无需创建新的类,就能满足我们的需求,也减少了代码的冗余。

//定义方法
new 接口/类名(参数列表){
		实现方法1(){
		}
		实现方法2(){
		}
		...
}

例如我们想自定义二维数组排序的规则?

public class Demo {
    public static void main(String[] args) {
        int[][] array = {{5,1},{2,8},{8,1},{1,6},{5,2}};
        Arrays.sort(array, new Comparator<int[]>() {
        	//1.匿名类中重写compare方法
            @Override
            public int compare(int[] o1, int[] o2) {
                //第一个数不相等则升序排列,若相等,则按第二个数升序排列
                if(o1[0] != o2[0]){
                    return o1[0]-o2[0];
                }else {
                    return o1[1]-o2[1];
                }
            }
        });
        System.out.println(Arrays.deepToString(array));
    }
}

总结:

  1. 匿名内部类没有类名
  2. 匿名内部类不可以声明静态变量(可以访问静态或非静态的成员),
  3. 匿名内部类不能定义静态的方法
  4. 匿名内部类不可以定义构造方法(在定义匿名类同时已经实例化对象)

七、抽象类

概念:在面向对象的概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描述对象的,如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类。
Java当中用Abstract关键字修饰的类,就叫做抽象类。

7.1浅谈为何要有抽象类

根本原因:无法描述一类事物的类
例子引入:比如现在想创建一个动物类,描述动物的一些共性,比如动物会吃东西,但是具体的动物吃的东西不尽相同,而我们在动物类中就很难去描述动物去吃什么东西。采用继承的思想,子类重新该方法,在添加具体的实现。

class Animal{
    public void eat(){
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃狗粮");
    }
}

class Pig extends Animal{
    @Override
    public void eat() {
        System.out.println("猪吃猪粮");
    }
}

有的人可能会说这不也很好的实现了吗?
一般的类确实也能满足该需求,抽象类主要是用来适配子类的通用特性,是被用来创建子类的模板,实际上有些父类中的方法没有必要重新,当我们成使用抽象类来定义时,这样就可以区分哪些方法需要重写,具有提示的作用,也是我们设计程序的一种思想,我相信随着我们逐渐深入的学习,对这些设计会感触颇深。

7.2抽象类的特性

在这里插入图片描述
总结:

  1. 抽象类使用abstract关键字修饰
  2. 包含抽象方法的类一定是抽象类,反之,抽象类不一定包含抽象方法。
  3. 抽象类必须要被继承使用,否则就没有存在的意义,继承的子类必须重写父类中的抽象方法(子类也是抽象类除外)
  4. 抽象类不能够实例化
  5. 抽象方法不能被private(用private修饰的方法,不能被子类重写,那该抽象方法体是空的就没有存在的意义了),static(static修饰的方法是静态的方法,可以直接被类名调用,而抽象类没有具体的方法体,调用没有意义),final(final修饰的方法不能被重写)修饰符修饰。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南 栀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值