01-初识面向对象

初识面向对象

类与对象

什么是对象?

在编程语言和现实世界中,对象是一个非常重要的概念。所谓“万物皆对象”,指的是现实存在的客观事物都是对象。

什么是面向对象?

①假如我们有一天去动物园看动物

②我们对管理员描述想看的动物需求。

  •  胖的
  • 可爱的

③管理员听后,带我们去看了熊猫班卜和黑熊吨吨

我们去动物园看动物的这个过程,实际上就是一个面向对象的过程。

我们去动物园看动物的时候,当说出我们需求的时候,此时的动物是虚拟的;当管理员带领我们去看动物的时候,此时的动物才是实体,这是我们生活中处理问题的方式。

类与对象的关系 

  • 类是模型(模板),确定对象将会拥有的特征(属性)和行为(方法)
  • 对象是类的实例表现
  • 类是对象的类型
  • 对象是特定类型的数据

属性和方法

属性:对象具有的各种静态特征——“对象有什么”

方法:对象具有的各种动态行为——“对象能做什么”

回到我们逛动物园的实例,动物具有的特征就是对象的属性;动物可以做的事情就是对象的方法

总结 

    • 抽象的概念
    • 模板
  • 对象
    • 一个实际存在的具体事物

创建类 

面向对象在java编程中的实现步骤:

创建一个宠物猫类Cat.java,描述该宠物猫的属性和行为方法

package animal;
/**
 * 宠物猫类
 * @author Zhao
 *
 */
public class Cat {
	
	//成员属性:名称、年龄、体重、品种
	String name;//名称
	int month;//年龄
	double weight;//体重
	String species;//品种
	
	//方法:跑、吃东西
	//跑动的方法
	public void run() {
		System.out.println("小猫快跑!");
	}
	//吃东西的方法
	public void eat() {
		System.out.println("小猫吃东西!");
	}

}

 实例化对象

 

创建一个测试类CatTest.java,去实例化对象,并调用对象的属性和方法。

package object.start;

/**
 * @author Ning
 * @date 2021/9/20 10:57
 */
public class CatTest {
    public static void main(String[] args) {
        //实例化对象 ——>通过new关键字
        Cat one = new Cat();
        //调用对象的属性
        one.name = "花花";
        one.month = 2;
        one.weight = 1000;
        one.species = "英国短毛猫";
        //调用对象的方法
        one.eat();
        one.run();
        //输出对象的属性值
        System.out.println("名字:"+one.name);
        System.out.println("年龄:"+one.month);
        System.out.println("体重:"+one.weight);
        System.out.println("品种:"+one.species);
    }
}

注意:对象的属性如果没有进行初始化,系统会默认地给对象的属性赋初始值。

整型的初始值为0

浮点型的初始值为0.0

字符串的初始值为null

单一职责原则 

 

我们会发现之前写的代码都是放在一个类里面,包括主方法;而在面向对象的编程中,主方法和封装属性、方法的类是拆开的,这就是 单一职责原则(单一功能原则) 

单一职责原则

所谓“单一职责原则”表示的是一个类中有且只有一个引起变化的原因。

简单地来说就是一个类最好只有一个功能。

比如说下面正在做实验的仓鼠:

假如我们想观察仓鼠的运动,那就只需要让它做跑动这一件事就可以了;如果既想让它跑,同时还让它跑一段距离再跳起来,那么这只仓鼠的内心是崩溃的。 

因此,在一个类中,如果该类承担的功能越多,那么此类的 交融与耦合度就会越高,被复用的可能性就会越低

交融、耦合性越高会发生什么? 

交融、耦合性越高可能会引发同类中其他职责的变化,进而影响整个程序的运行。

这就好比我们生活中过马路的情景,很多人喜欢边走路边玩手机;也有很多人喜欢边开车边打电话,因此一旦发生事故就是一件非常可怕的事情。 

new关键字 

在面向对象中,我们通过new关键字去实例化对象。 

实例化对象

实例化对象的过程可以分成两个部分:

①声明对象        Cat one

②实例化对象        new Cat();

 

声明对象的时候,此时内存空间中的one是null,那么它是无法去访问属性和方法的。

为什么实例化对象后就可以访问属性和方法了? 

当实例化对象后,会在内存的堆空间中去开辟一块空间,从而完成对象信息的初始化操作。

注意:声明对象和实例化对象在不同的空间中

声明对象在栈空间中;实例化对象在堆空间中。 

那么栈空间和堆空间是怎么关联起来的? 

实例化对象后,会将对象在堆空间中的内存地址存放到栈中,从而使声明的对象指向实例化的空间。

 

如果使用new关键字实例化一个对象,两个对象会发送冲突吗? 

我们修改一下CatTest.java的代码,我们再new一个对象

package object.start;

/**
 * @author Ning
 * @date 2021/9/20 10:57
 */
public class CatTest {
    public static void main(String[] args) {
        //实例化对象 ——>通过new关键字
        Cat one = new Cat();
        //再实例化一个对象
        Cat two = new Cat();
        //调用对象的属性
        one.name = "花花";
        one.month = 2;
        one.weight = 1000;
        one.species = "英国短毛猫";
        //给two的属性赋值
        two.name = "凡凡";
        two.month = 1;
        two.weight = 800;
        two.species = "中华田园猫";
        //输出对象的属性值
        System.out.println("名字:"+one.name);
        System.out.println("年龄:"+one.month);
        System.out.println("体重:"+one.weight);
        System.out.println("品种:"+one.species);

        System.out.println("------------------------------");

        System.out.println("名字:"+two.name);
        System.out.println("年龄:"+two.month);
        System.out.println("体重:"+two.weight);
        System.out.println("品种:"+two.species);
    }
}

运行结果:

名字:花花

年龄:2

体重:1000.0

品种:英国短毛猫


名字:凡凡

年龄:1

体重:800.0

品种:中华田园猫

我们发现使用new关键字实例化的两个对象是不会发生冲突的。

每当我们使用new关键字时,都会在堆空间中开辟一块空间来存储对象的地址,虽然都是猫类,但是所指向的地址不同,就算二者的属性值完全相同,二者之间是互不影响的。

这就好比我们有两套房子,就算房子的外观内饰一模一样,房子的钥匙也是两套不同的钥匙。

对象实例化是不是只有new这一种实现方式呢?

我们修改一下CatTest.java代码

package object.start;

/**
 * @author Ning
 * @date 2021/9/20 10:57
 */
public class CatTest {
    public static void main(String[] args) {
        //实例化对象 ——>通过new关键字
        Cat one = new Cat();
        //将对象one赋值给对象two
        Cat two = one;
        //调用对象的属性
        one.name = "花花";
        one.month = 2;
        one.weight = 1000;
        one.species = "英国短毛猫";
        //给two的属性赋值
        two.name = "凡凡";
        two.month = 1;
        two.weight = 800;
        two.species = "中华田园猫";
        //输出对象的属性值
        System.out.println("名字:"+one.name);
        System.out.println("年龄:"+one.month);
        System.out.println("体重:"+one.weight);
        System.out.println("品种:"+one.species);

        System.out.println("------------------------------");

        System.out.println("名字:"+two.name);
        System.out.println("年龄:"+two.month);
        System.out.println("体重:"+two.weight);
        System.out.println("品种:"+two.species);
    }
}

运行结果:

名字:凡凡

年龄:1

体重:800.0

品种:中华田园猫


名字:凡凡

年龄:1

体重:800.0

品种:中华田园猫

我们发现对象的属性值都成为了对象two设置的属性值。

这实际上是对象one将内存地址复制了一份,放入到了对象two里面,此时,二者都指向了同一块内存区域,因此二者无论是谁对属性进行修改,都会影响另一方。

这就好比是一个房子里面住进了两个人,任何一个人都可以对房子进行装修。

构造方法

构造方法也称“构造器”、“构造函数”。可以通过构造方法来完成对象初始化的相关设置。

构造方法的语法 

访问修饰符 构造方法名(参数列表){

初始化代码块

}  

构造方法的相关规则 

①        构造方法与类名必须相同且无返回值

②        只能在对象实例化的时候使用

③        当没有指定构造方法时,系统会默认提供无参构造方法

④        当有指定构造方法,无论是有参、无参构造方法,都不会自动添加无参构造方法

⑤        一个类中可以有多个构造方法

无参构造方法 

我们在写Cat.java文件中的代码时,没有写无参构造方法,系统会给我们自动地添加一个无参构造方法,那这次我们手动在Cat.java中添加无参构造方法

//无参构造方法
public Cat(){
    System.out.println("Cat的无参构造方法,这是我们手动添加的。。。");
}

 在CatTest.java中去调用我们手动添加的无参构造方法

package object.start;

/**
 * @author Ning
 * @date 2021/9/20 10:57
 */
public class CatTest {
    public static void main(String[] args) {
        //实例化对象 ——>通过new关键字
        Cat one = new Cat();    //系统通过无参构造方法初始化对象
    }
}

运行结果:

Cat的无参构造方法,这是我们手动添加的。。。

有参构造方法 

我们之前给对象的属性赋初始值的时候是通过 对象名.属性名=属性值; 去完成赋值。当对象的属性过多时,一个个赋值会比较麻烦,因此我们可以在类中添加有参构造方法对属性的值进行初始化操作。 

在Cat.java中添加有参构造方法

//有参构造方法
public Cat(String name, int month, double weight, String species) {
     name = name;
     month = month;
     weight = weight;
     species = species;
}

在CatTest.java中进行测试

package object.start;

/**
 * @author Ning
 * @date 2021/9/20 10:57
 */
public class CatTest {
    public static void main(String[] args) {
        //实例化对象 ——>通过new关键字
        //使用有参构造方法对属性进行初始化
        Cat one = new Cat("花花",2,1000,"英国短毛猫");
        System.out.println("名字:"+one.name);
        System.out.println("年龄:"+one.month);
        System.out.println("体重:"+one.weight);
        System.out.println("品种:"+one.species);
    }
}

运行结果:

名字:null

年龄:0

体重:0.0

品种:null

拓展 

我们明明通过有参构造方法对属性值进行初始化,但是为什么没有赋值成功?

 

我们犯了一个逻辑错误,我们的有参构造方法中出现了一条警告信息——The assignment to variable name has no effect. 该变量未起作用。

原因是因为当参数列表中的参数名称与成员变量名称同名时,由于没有具体指定,变量到底是构造方法中的变量还是成员变量,系统会采用就近原则,因此不会给成员变量赋值。 

解决方法有两种:

①        修改参数列表中的变量名 Cat.java

//有参构造方法
public Cat(String newName, int newMonth, double newWeight, String newSpecies) {
    name = newName;
    month = newMonth;
    weight = newWeight;
    species = newSpecies;
}

CatTest.java运行后的结果:

名字:花花

年龄:2

体重:1000.0

品种:英国短毛猫

②        通过this关键字 

this关键字

this可以指代当前对象,所谓当前对象就是谁调用this就指向谁。this关键字即可以访问属性也可以访问方法。

通过this关键字修改Cat.java的有参构造方法

//有参构造方法
public Cat(String name, int month, double weight, String species) {
    this.name = name;
    this.month = month;
    this.weight = weight;
    this.species = species;
}

 CatTest.java运行结果:

名字:花花

年龄:2

体重:1000.0

品种:英国短毛猫

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值