第一章节02 类型与对象的问题

第一章节02

数据类型扩展

整数的进制问题

正如我们可以从语法中得出的那样,整数文字有四种类型:

  • 纯十进制,必须以非零数字开头。

  • 八进制,任何以0开头的数字(包括纯0)。(octal八进制)

  • 二进制,需要前缀0b0B。(binary二进制)

  • 十六进制,需要前缀0x0X。(hex十六进制)

浮点数的数据问题

运算以下代码

float f = 2.4;
double d =2.4;
System.out.println(f==d);

避免用浮点数进行比较

字符型本质问题

字符的本质都是数字

存在一张编码表 Unicode 每个字符都有对应的数字

类型转换‘

  • 优先级

低——————————————————————————高

image-20220903121328653

由图可知小数优先级高于整数

  • 强制类型转换 (类型)变量名 高—>低
  • 自动类型转换 低—>高

//不能对布尔值进行转换

//不能把对象类型转换成不相干的类型

//高—>低要强制转换

//转换的过程中可能存在内存溢出,精度损失(直接舍弃)

变量与常量

变量

变量名

变量类型

作用域

  • 成员变量:作用范围是整个类,相当于C中的全局变量,定义在方法体和语句块之外,一般定义在类的声明之下;成员变量包括实例变量和静态变量(类变量);
    实例变量:独立于与方法之外的变量,无static修饰,声明在一个类中,但在方法、构造方法和语句块之外,数值型变量默认值为0,布尔型默认值为false,引用类型默认值为null;
  • 静态变量(类变量):独立于方法之外的变量,用static修饰,默认值与实例变量相似,一个类中只有一份,属于对象共有,存储在静态存储区,经常被声明为常量,调用一般是类名.静态变量名,也可以用对象名.静态变量名调用;
  • 局部变量:类的方法中的变量,访问修饰符不能用于局部变量,声明在方法、构造方法或语句块中,在栈上分配,无默认值,必须经初始化

实例变量

有点像模板类一样 前面定义,在函数中new出来,实例化。

实例变量定义完如果不初始化,会自动有初始值

  • 整型和浮点型 是0和0.0
  • boolean是 flase
  • char是 image-20220903164457813
  • 其他的都是null(string,数组)

常量

加上一个单词 final(修饰符) 常量名字常用全大写

今日疑问

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

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

但是此对象非彼对象哦~

1.什么是对象?

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

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

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

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

2.什么是面向对象?

  • 面向过程:了解面向对象前,先了解面向过程。我们之前所编写的程序都是面向过程的,分析解决问题的步骤,然后按照步骤第一步做什么,第二步做什么......如果将步骤写成了方法,就依次调用方法。适合处理简单的问题。
  • 面向对象:而面向对象是一种抽象的分类的思想,分析解决问题需要从哪几个方面出发,即有哪几个分类,然后对这些分类进行单独的面向过程的思考,每一个分类需要具体的完成什么。用于处理复杂的问题。

例:

  • 面向过程:一个人要喝水,那么他首先就看看杯子里有没有水,有的话就喝水,没有的话,就倒水再喝水。
  • 面向对象:现在要建一栋房子,这就更复杂了,首先需要分为三大类,需要设计人员设计图纸,需要建筑人员建房子,需要装修人员装修;而设计人员怎么设计图纸,建筑人员怎么建造,装修人员怎么装修又是每一个分类的具体细节。

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

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

3.类与对象的关系

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

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

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

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

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

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

  • 类是对象的模板。(在类中定义了对象的属性和行为,即提供了对象的基本框架。)
  • 对象是类的实例。(我们通过类来创建对象。)
  • 类是具有共同属性和行为的对象的抽象。(一个学生类,张三是学生,李四也是学生,他们拥有姓名、性别、学号等,也有共同的行为,学习。)

4.类的定义

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

package com.dh.oop;

public class OopDemo01 {
}

权限修饰符

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

img
img
img

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

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

类是用来实现一个功能的,如果权限被设置了就丧失了原本创建许多类然后组织起来实现一个项目的目的

那可以定义多个类吗?

img

img

我们可以看到,在一个.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,但是输出结果为李四在学习,可以证明,使用的是局部变量:

img

对象的声明

语法:类名 对象名 ;

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

img

错误原因分析:在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");
    }
}

代码运行结果:

img

参考https://www.cnblogs.com/denghui-study/p/14295499.html

posted @ 2022-09-03 23:07  A31  阅读(15)  评论(0编辑  收藏  举报