什么是对象?对象与类的关系?对象的声明和使用

你听过这个笑话吗?你有对象吗?没有的话就new一个吧!

但是此对象非彼对象哦~

1.什么是对象?

Java是一门面向对象的语言(OOP),在Java中,有一句话叫:万事万物皆为对象。

我们生活中的每一件东西都可以看作是一个对象,包括我们本身都是一个对象。

这是一种抽象的思想,我们将一件事物提取出特征和行为,将特征定义为属性,将行为封装成方法

如,一个人,特征有姓名、年龄、性别、职业等等,行为有吃饭、睡觉、学习等等。

2.什么是面向对象?

  • 面向过程:了解面向对象前,先了解面向过程。我们之前所编写的程序都是面向过程的,分析解决问题的步骤,然后按照步骤第一步做什么,第二步做什么......如果将步骤写成了方法,就依次调用方法。适合处理简单的问题。

  • 面向对象:而面向对象是一种抽象的分类的思想,分析解决问题需要从哪几个方面出发,即有哪几个分类,然后对这些分类进行单独的面向过程的思考,每一个分类需要具体的完成什么。用于处理复杂的问题。

例:

  • 面向过程:一个人要喝水,那么他首先就看看杯子里有没有水,有的话就喝水,没有的话,就倒水再喝水。

  • 面向对象:现在要建一栋房子,这就更复杂了,首先需要分为三大类,需要设计人员设计图纸,需要建筑人员建房子,需要装修人员装修;而设计人员怎么设计图纸,建筑人员怎么建造,装修人员怎么装修又是每一个分类的具体细节。

而我们到最后要用Java来完成的东西,肯定是复杂的,所以面向对象思想极其重要。我们主要从以下思考出发:

对象有哪些?对象的特征(属性)和行为(方法)是什么?对象与对象的关系是什么?

3.类与对象的关系

我们知道,不管使用什么思想,Java的代码一定是编写在类中的,所以我们的对象也肯定是在类中的,而上述我们又提到,我们要在类中定义对象的特征(属性)和行为(方法),所以我们可以总结面向对象编程的本质:

面向对象编程的本质:以类的形式组织代码,以对象的形式组织(封装)数据。

那类是对象是什么关系呢?

从认识论的角度来看:我们先确定了对象,再为该对象书写一个类。(我们确定了学生为一个对象,就需要定义一个对应的学生类,在类 中书写学生的特征(属性)和行为(方法));

从代码运行角度来看:我们是先有了类,再使用类创造了对象。(我们代码的运行首先会加载该学生类,再运行该类中的代码,如对象操 作等内容)。

所以,类与对象的关系总结如下:

类是对象的模板。(在类中定义了对象的属性和行为,即提供了对象的基本框架。)

对象是类的实例。(我们通过类来创建对象。)

类是具有共同属性和行为的对象的抽象。(一个学生类,张三是学生,李四也是学生,他们拥有姓名、性别、学号等,也有共同的行为,学习。)

4.类的定义

之前,我们没有具体的探究过类的定义,直接使用的是IDEA中自动生成的模板,我们现在再来看一下这个模板:

package com.dh.oop;

public class OopDemo01 {
}

权限修饰符

自动生成的类中的权限符为最大的public,我们换成其它的修饰符会怎么样呢?



可以看到,只能用public或者是default这两个权限修饰符来修饰类,protected和private是不能用来修饰类的!

其实也不难理解,因为类是Java的最小单位,我们解决问题就是通过一个一个类联合起来的,如果权限符为protected和private了,就有了很大的访问局限,这个类差不多就是个单独的类,和别的类没什么关系,那这个类的意义也就不大了。就像煮饭,菜刀拿来切菜,但是你把菜刀锁进了柜子里,只有拥有那把钥匙的厨师才能使用它,那这菜刀存在的意义就不大了。

那可以定义多个类吗?

我们可以看到,在一个.java文件中,可以定义多个类,但是只能有一个被public修饰。

但是一般不建议在一个java文件中书写多个类,一个java文件一般只书写一个类,不就是多建一个java文件的事嘛,也不麻烦对不对

class

Java使用class关键字来定义一个类。

类名

类名的定义要符合标识符的命名规则,最好见名知意,一般为驼峰命名法,每个单词的首字母都大写。

需要注意的是:在同一个包下的类不允许重名,在不同包下的类允许同名。

注意:

在类体中不能直接出现可执行语句,会直接红色波浪线报错

  • if、switch、while、do...while、for;
  • 打印语句;
  • 赋值语句;
  • ......

5.对象的声明和使用

首先,我们要在类中定义对象的属性和方法:

package com.dh.oop;

//学生类
public class Student {
    
    //属性和方法是同一级别的
    
    //属性
    public String name;
    public int age;
    public char sex;
    public int num;
    
    //方法
    public void study(){
        System.out.println("学生学习");
    }

    //程序入口:main方法
    public static void main(String[] args) {
        
    }
}

成员变量、局部变量、类变量

之前我们都是将变量直接定义在方法内部的,现在却定义在了方法的外部。这里就涉及到了成员变量和局部变量的概念了。

成员变量:定义在类的内部,方法的外部。具有默认值(整数为0,浮点数为0.0,布尔值为false,char为'',引用为null);
	
         别名:实例变量。

  	 作用域:类中。(本类中可直接使用,其他类也可能可以使用对象调用,具体看是否有权限)

	 使用方法:对象.变量调用,this.变量名调用,直接调用。

局部变量:定义在方法的内部。没有默认值,必须赋初始值才能使用,否则使用会报错;

	 作用域:定义的那个方法中。

	 使用方法:在方法中直接使用。

类变量:被static修饰的变量,也是成员变量的一种。**该变量属于类,凌驾于对象之上,只有一份,给所有的实例对象共享。

       别名:静态变量。

       作用域:类中。(本类中可直接使用,其他类也可能可以使用对象调用或者类名调用,具体看是否有权限)

       注意:只能修饰成员变量,不能修饰局部变量。

       使用方法:在static方法中直接使用,可以通过对象.变量名调用,也可以直接使用类名.变量名调用。

(可能有些现在不理解的,会慢慢在后续讲到~)

成员变量和局部变量可重名,重名时遵循就近原则:

package com.dh.oop;

public class Student {

    public String name = "张三";

    public static void study(String name){
        System.out.println(name +"在学习");
    }

    public static void main(String[] args) {
        study("李四");
    }
}

局部变量和成员变量都为name,但是输出结果为李四在学习,可以证明,使用的是局部变量:

对象的声明

语法:类名 对象名 ;

Student student;

对象的声明可以在类体中,也可以在方法中。

对象的实例化

语法:对象名 = new 类名();

student = new Stdent();

扩展:在类体中实例化自身而导致的栈溢出问题

针对上述在类体中声明对象,如果该对象是在static方法中实例化的话,注意对象也需要定义成static。如果直接在类体中实例化对象,当其他方法中有实例化对象的操作时,会发生栈溢出错误:

package com.dh.oop;

public class StudentDemo {
    public String name;
    public int age;

    StudentDemo s = new StudentDemo();//栈溢出

    public static void main(String[] args) {

        StudentDemo studentDemo = new StudentDemo();
    }
}

错误原因分析:在main方法中new一个对象的话,会初始化该类的成员变量,变量里又有new操作,又要去初始化成员变量,又有new,然后就一直得在栈里开辟空间,就会导致栈溢出错误。

解决方案:将需要在类中实例化的对象定义成static。

原理:如果是static的话,只在首次new的时候开辟内存,new新对象的时候,再就不会开辟新的内存,直接指向第一个,就不会栈内存不够而溢出了。

边声明边实例化

语法:类名 对象名 = new 类名();

//声明一个student对象
Student student = new Student();
//可声明多个,不可重名
Student student1 = new Student();

//student和student是不同的两个对象

推荐使用这种方法!

对象的赋值和使用

语法:

属性的赋值:对象名.变量名 = 值;

属性的使用:对象名.变量名;

方法的使用:对象名.方法(【参数】);

//属性的使用
student.name = "zhangsan";
student.age = 18;
student.sex = '男';
student.num = 001;
System.out.println(student.name+"\t"+student.age+"\t"+student.sex+"\t"+student.num);

//方法的使用
student.study("李四");

不同的对象可以自定义其自己的属性值

//不同的对象可以有不同的属性
student1.name = "lisi";
student1.age = 19;
student1.sex = '男';
student1.num = 002;
System.out.println(student1.name+"\t"+student1.age+"\t"+student1.sex+"\t"+student1.num);
//不同的对象调用方法
student1.study("lisi");

总代码:

package com.dh.oop;

public class Student {

    //可以赋初值,如果不赋值的话也会有默认值
    public String name = "张三";
    public int age;
    public char sex;
    public int num;
    
    //成员方法
    public void study(String name){
        System.out.println(name+"在学习");
    }
    
    public static void main(String[] args) {

        //声明一个student对象
        Student student = new Student();
        //可声明多个,但不可重名
        Student student1 = new Student();

        //属性的使用
        student.name = "zhangsan";
        student.age = 18;
        student.sex = '男';
        student.num = 1001;
        System.out.println(student.name+"\t"+student.age+"\t"+student.sex+"\t"+student.num);

        //方法的使用
        //对象可以在static方法中直接调用非static方法(如果直接调用就只能调用static方法,对象的强大性来了!)
        student.study("zhangsan");

        //不同的对象可以有不同的属性
        student1.name = "lisi";
        student1.age = 19;
        student1.sex = '男';
        student1.num = 1002;
        System.out.println(student1.name+"\t"+student1.age+"\t"+student1.sex+"\t"+student1.num);
        //不同的对象调用方法
        student1.study("lisi");
    }
}

代码运行结果:


本人水平有限,若有错误望指出~感激不尽!

posted @ 2021-01-18 22:11  deng-hui  阅读(5940)  评论(1编辑  收藏  举报