首页 > 编程语言 >Java基础入门--第三章--面向对象(上)

Java基础入门--第三章--面向对象(上)

时间:2024-03-31 17:04:03浏览次数:32  
标签:Java name 构造方法 -- age 面向对象 Student public String

面向对象(上)

1.1 面向对象的思想

1 封装性
封装是面向对象的核心思想,它有两层含义,第一层含义是指把对象的属性和行为看成是一个密不可分的整体,将这两者“封装”在一起(即封装在对象中);另外一层含义指“信息隐藏”,将不想让外界知道的信息隐藏起来。
2 继承性
继承性主要描述的是类与类之间的关系,通过继承,可以在原有类的基础上,对原有类的功能进行扩展。
3 多态性
多态性是指在一个类中定义的属性和方法被其他类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。

2 类与对象

2.1 类的定义

在面向对象的思想中最核心的就是对象,创建对象的前提是需要定义一个类,类是Java中一个重要的引用数据类型,也是组成Java程序的基本要素,所有的Java程序都是基于类的。
类是对象的抽象,用于描述一组对象的共同特征和行为。类中可以定义成员变量和成员方法,其中,成员变量用于描述对象的特征,成员变量也被称作对象的属性;成员方法用于描述对象的行为,可简称为方法。

class 类名{
   成员变量;
   成员方法;
}

根据上述格式定义一个学生类,成员变量包括姓名(name)、年龄(age)、性别(sex);成员方法包括读书read()。学生类定义的示例代码如下所示。

        class Student {
            String name;        // 声明String类型的变量name
            int age;            // 声明int类型的变量age
            String sex;        // 声明String类型的变量sex

            // 定义 read () 方法
            void read() {
                System.out.println("大家好,我是" + name + ",我在看书!");
            }
        }

以上代码中定义了一个学生类。其中,Student是类名,name、age、sex是成员变量,read()是成员方法,在成员方法read()中可以直接访问成员变量name。

在Java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量。

2.2 对象的创建与使用

上面定义了一个Student类,要想使用一个类则必须要创建该类的对象。在Java程序中可以使用new关键字创建对象,使用new关键字创建对象的具体格式如下:

类名 对象名称 = null;
对象名称 = new 类名();

上述格式中,创建对象分为声明对象和实例化对象两步,也可以直接通过下面的方式创建对象,具体格式如下:

类名 对象名称 = new 类名();

例如:Student stu = new Student();

创建对象后,可以使用对象访问类中的某个属性或方法,对象属性和方法的访问通过“.”运算符实现,具体格式如下。

对象名称.属性名
对象名称.方法名

class Student {
    String name;     // 声明姓名属性

    void read() {
        System.out.println("大家好,我是" + name + ",我在看书!");
    }
}

public class Example03 {

    public static void main(String[] args) {
        Student stu = new Student();
        stu.name = "李华";
        stu.read();
    }
}

2.3 对象的引用传递

类属于引用数据类型,引用数据类型就是指内存空间可以同时被多个栈内存引用。

class Student {
    String name;
    int age;

    void read() {
        System.out.println("大家好,我是" + name + ",年龄" + age);
    }
}

public class Example03 {
    public static void main(String[] args) {
        Student stu1 = new Student();
        Student stu2 = null;
        stu2=stu1;
        stu1.name = "小明";
        stu1.age = 20;
        stu2.age = 50;
        stu1.read();
        stu2.read();

    }
}

在这里插入图片描述

stu1对象和stu2对象输出的内容是一致的,这是因为stu2对象获得了stu1对象的堆内存空间的使用权。第14行代码对stu1对象的age属性赋值之后,第15行代码通过stu2对象对age属性值进行了修改。实际上所谓的引用传递,就是将一个堆内存空间的使用权给多个栈内存空间使用,每个栈内存空间都可以修改堆内存空间的内容。
在这里插入图片描述

在这里插入图片描述
第一步声明对象stu1和stu2,并使用new创建Student对象赋值给stu1,使用new创建对象时会开辟一个堆内存空间,对象stu1指向开辟的堆内存地址0x001;
第二步通过对象stu1给对象stu2分配内存空间使用权,对象stu2指向堆内存地址0x001;第三步由于对象stu1指向堆内存地址0x001,所以对象stu1修改属性值时,就是修改堆内存中对象的值,堆内存中name的值修改为“小明”,age的值修改为20;
第四步与第三步类似,对象stu2也指向堆内存地址0x001,堆内存中age的值修改为50,最终结果对象stu1的age属性值也是50。

2.4 访问控制权限

在Java中,针对类、成员方法和属性,Java提供了4种访问控制权限,分别是private、default、protected和public。下面通过一张图将这4种访问控制权限按级别由小到大依次列出。
在这里插入图片描述
(1)private:private属于私有访问权限,用于修饰类的属性和方法,也可以修饰内部类。类的成员一旦使用了private关键字修饰,则该成员只能在本类中进行访问。

(2)default:default属于默认访问权限,如果一个类中的属性或方法没有任何的访问权限声明,则该属性或方法就是默认的访问权限,默认的访问权限可以被本包中的其他类访问,但是不能被其他包的类访问。

(3)protected:protected属于受保护的访问权限。如果一个类中的成员使用了protected访问权限,则只能被本包及不同包的子类访问。

(4)public:public属于公共访问权限。如果一个类中的成员使用了public访问权限,则该成员可以在所有类中被访问,不管是否在同一包中。

访问范围privatedefaultprotectedpublic
同一类中
同一包中的类
不同包的子类
全局范围

如果一个Java源文件中定义的所有类都没有使用public修饰,那么这个Java源文件的文件名可以是一切合法的文件名;如果一个源文件中定义了一个public修饰的类,那么这个源文件的文件名必须与public修饰的类名相同。

3 封装性

3.1 为什么要封装

在Java面向对象的思想中,封装是指一种将类的实现细节包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止本类的代码和数据被外部类定义的代码随机访问。

class Student{
    String name;
    int age;
    void read(){
        System.out.println("大家好,我是"+name+",年龄"+age);
    }
}
public class Example03 {
    public static void main(String[] args){
        Student stu= new Student();
        stu.name="张三";
        stu.age=-19;
        stu.read();
    }
}

代码将age(年龄)属性赋值为-18岁,这在程序中是不会有任何问题的,因为int的值可以取负数。但在现实中,-18明显是一个不合理的年龄值。为了避免这种错误的发生,在设计Student类时,应该对成员变量的访问作出一些限定,不允许外界随意访问,这就需要实现类的封装。

3.2 如何实现封装

类的封装是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,而是通过该类提供的方法实现对内部信息的操作访问。封装的具体实现过程是,在定义一个类时,将类中的属性私有化,即使用private关键字修饰类的属性,私有属性只能在它所在的类中被访问。如果外界想要访问私有属性,需要提供一些使用public修饰的公有方法,其中包括用于获取属性值的getXxx()方法(也称为getter方法)和设置属性值的setXxx()方法(也称为setter方法)。

class Student{
    private String name;        	// 声明姓名属性
    private  int age;           	// 声明年龄属性
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if(age < 0){
            System.out.println("您输入的年龄有误!");
        } else {
            this.age = age;
        }
    }
    public void read() {
        System.out.println("大家好,我是"+name+",年龄"+age);
    }
}
public class Example03 {
    public static void main(String[] args) {
        Student stu = new Student();		// 创建学生对象
        stu.setName("张三");	              	// 为对象的name属性赋值
        stu.setAge(-18);	               	// 为对象的age属性赋值
        stu.read();	                        	// 调用对象的方法
    }
}

在这里插入图片描述

4 构造方法

4.1 定义构造方法

构造方法是一个特殊的成员方法,在定义时,有以下几点需要注意。
(1)构造方法的名称必须与类名一致。
(2)构造方法名称前不能有任何返回值类型的声明。
(3)不能在构造方法中使用return返回一个值,但可以单独写return语句作为方法的结束。

class Student{
    public Student() {
        System.out.println("调用了无参构造方法");
    }
}
public class Example03 {
    public static void main(String[] args) {
        System.out.println("声明对象...");
        Student stu = null;           		//声明对象
        System.out.println("实例化对象...");
        stu = new Student();     			//实例化对象
    }
}

在这里插入图片描述
由上图所示的运行结果分析可知,当调用关键字new实例化对象时,程序调用了Student类的无参构造方法。
一个类中除了定义无参的构造方法外,还可以定义有参的构造方法,通过有参的构造方法可以实现对属性的赋值。通过下面一个案例演示有参构造方法的定义与调用。

class Student {
    private String name;
    private int age;

    public Student(String n, int a) {
        name = n;
        age = a;
        System.out.println("调用了有参构造方法");
    }

    public void read() {
        System.out.println("我是:" + name + ",年龄:" + age);
    }
}

public class Example03 {
    public static void main(String[] args) {
        Student stu = new Student("张三", 16);
        stu.read();
    }
}

在这里插入图片描述

4.2 构造方法的重载

与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,但是需要每个构造方法的参数类型或参数个数不同。在创建对象时,可以通过调用不同的构造方法为不同的属性赋值。

class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String n) {
        name = n;
        System.out.println("调用了一个参数的构造方法");
    }

    public Student(String n, int a) {
        name = n;
        age = a;
        System.out.println("调用了两个参数的构造方法");
    }

    public void read() {
        System.out.println("我是:" + name + ",年龄:" + age);
    }
}

public class Example03 {
    public static void main(String[] args){
        Student stu1=new Student("李华");
        Student stu2=new Student("张三",16);
        stu1.read();
        stu2.read();

    }
}

在这里插入图片描述

5 this关键字

5.1 使用this关键字调用本类中的属性

在实际开发中,如果成员变量和局部变量的名称设置成一样的,会导致成员变量和局部变量的名称冲突。

class Student {
    private String name;
    private int age;
    // 定义构造方法
    public Student(String name,int age) {
        name = name;
        age = age;
    }
    public String read(){
        return "我是:"+name+",年龄:"+age;
    }
}
public class Example03 {
    public static void main(String[] args) {
        Student stu = new Student("张三", 18);
        System.out.println(stu.read());
    }
}

在这里插入图片描述
为了解决这个问题,Java提供了关键字this指代当前对象,通过this可以访问当前对象的成员。修改上述代码,使用this关键字指定当前对象属性,具体代码如下所示。

class Student {
    private String name;
    private int age;
    // 定义构造方法
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public String read(){
        return "我是:"+name+",年龄:"+age;
    }
}
public class Example03 {
    public static void main(String[] args) {
        Student stu = new Student("张三", 18);
        System.out.println(stu.read());
    }
}

在这里插入图片描述

5.2 使用this关键字调用成员方法

class Student {
	public void openMouth() {
		...
	}
	public void read() {
		this.openMouth();
	}
}

上述代码中,在read()方法中使用this关键字调用了openMouth()方法。需要注意的是此处的this关键字也可以省略不写。

5.3 使用this关键字调用构造方法

class Student {
    private String name;
    private int age;
    public Student () {
        System.out.println("调用了无参的构造方法");
    }
    public Student (String name,int age) {
        this();                  // 调用无参的构造方法
        this.name = name;
        this.age = age;
    }
    public String read(){
        return "我是:"+name+",年龄:"+age;
    }
}
public class Example03 {
    public static void main(String[] args) {
        Student stu = new Student("张三",18);    // 实例化 Student对象
        System.out.println(stu.read());
    }
}

在这里插入图片描述
使用this调用类的构造方法时,应注意以下三点。
(1)只能在构造方法中使用this调用其他的构造方法,不能在成员方法中通过this调用构造方法。
(2)在构造方法中,使用this调用其他构造方法的语句必须位于第一行,且只能出现一次。
(3)不能在一个类的两个构造方法中使用this互相调用。

6 代码块

代码块,简单来讲,就是用{}括号括起来的一段代码,根据位置及声明关键字的不同,代码块可以分为4种:普通代码块、构造块、静态代码块、同步代码块。本节将针对普通代码块和构造块进行讲解。

普通代码块就是直接在方法或是语句中定义的代码块
构造代码块是直接在类中定义的代码块。

7 static关键字

7.1 静态属性

如果在Java程序中使用static修饰属性,则该属性称为静态属性(也称全局属性),静态属性可以使用类名直接访问,访问格式如下。

类名.属性名
class Student {
    String name;                                        // 定义name属性
    int age;                                            // 定义age属性
    String school = "A大学";                            // 定义school属性

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

    public void info() {
        System.out.println("姓名:" + this.name + ",年龄:" + this.age +
                ",学校:" + school);
    }
}

public class Example03 {
    public static void main(String[] args) {
        Student stu1 = new Student("张三", 18);    // 创建学生对象
        Student stu2 = new Student("李四", 19);
        Student stu3 = new Student("王五", 20);
        stu1.info();
        stu2.info();
        stu3.info();
        //修改stu1对象的school的值
        stu1.school = "B大学";
        System.out.println("修改stu1学生对象的学生信息为B大学后");
        stu1.info();
        stu2.info();
        stu3.info();
    }
}

在这里插入图片描述
由上图可知,张三的学校信息由A大学修改为了B大学,而李四和王五的大学信息没有变化,表明非静态属性是对象所有,改变当前对象的属性值,不影响其他对象的属性值。

假设A大学改名成了B大学,而此时Student类已经产生了10万个学生对象,那么意味着,如果要修改这些学生对象的学校信息,则要把这10万个对象中的学校属性全部修改,共修改10万遍,这样肯定是非常麻烦的。

为了解决上述问题,可以使用static关键字修饰school属性,将其变为公共属性。这样,school属性只会分配一块内存空间,被Student类的所有对象共享,只要某个对象进行了一次修改,全部学生对象的school属性值都会发生变化。

class Student {
    String name;                    					// 定义name属性
    int age;                         					// 定义age属性
    static String school = "A大学";    						// 定义school属性
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void info(){
        System.out.println("姓名:" + this.name+",年龄:" +this. age+
                ",学校:" + school);
    }
}
public class Example03 {
    public static void main(String[] args) {
        Student stu1 = new Student("张三",18);    // 创建学生对象
        Student stu2 = new Student("李四",19);
        Student stu3 = new Student("王五",20);
        stu1.info();
        stu2.info();
        stu3.info();
        stu1.school = "B大学";//修改stu1对象的school的值
        System.out.println("修改stu1学生对象的学生信息为B大学后");
        stu1.info();
        stu2.info();
        stu3.info();
    }
}

在这里插入图片描述
static关键字只能修饰成员变量,不能修饰局部变量,否则编译器会报错。

7.2 静态方法

如果想要使用类中的成员方法,就需要先将这个类实例化。而在实际开发时,开发人员有时希望在不创建对象的情况下,通过类名就可以直接调用某个方法,这时就需要使用静态方法,要实现静态方法只需要在成员方法前加上static关键字。
同静态变量一样,静态方法也可以通过类名和对象访问,具体如下所示。

类名.方法

或者

实例对象名.方法

class Student {
    private static String school = "A大学";            // 定义school属性
    private String name;                                // 声明name属性
    private int age;                                    // 声明age属性

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

    public static String getSchool() {
        return school;
    }

    public static void setSchool(String s) {
        school = s;
    }

    public void info() {
        System.out.println("姓名:" + this.name + ",年龄:" + this.age +
                ",学校:" + school);
    }
}

class Example03 {
    public static void main(String[] args) {
        Student stu1 = new Student("张三", 18);      // 创建学生对象stu1
        Student stu2 = new Student("李四", 19);      // 创建学生对象stu2
        Student stu3 = new Student("王五", 20);      // 创建学生对象stu3
        System.out.println("----修改前----");
        stu1.info();
        stu2.info();
        stu3.info();
        System.out.println("----修改后----");
        Student.setSchool("B大学");              //为静态属性school重新赋值
        stu1.info();
        stu2.info();
        stu3.info();
    }
}

在这里插入图片描述
静态方法只能访问静态成员,因为非静态成员需要先创建对象才能访问,即随着对象的创建,非静态成员才会分配内存。而静态方法在被调用时可以不创建任何对象。

7.3 静态代码块

在Java类中,用static关键字修饰的代码块称为静态代码块。当类被加载时,静态代码块就会执行,由于类只加载一次,所以静态代码块只执行一次。在程序中,通常使用静态代码块对类的成员变量进行初始化。

class Student{
    String name;    //成员属性
    {
        System.out.println("我是构造代码块");
    }
    static {
        System.out.println("我是静态代码块");
    }
    public Student(){   //构造方法
        System.out.println("我是Student类的构造方法");
    }
}
class Example03{
    public static void main(String[] args) {
        Student stu1 = new Student();
        Student stu2 = new Student();
        Student stu3 = new Student();
    }
}

在这里插入图片描述
首先介绍了面向对象的思想;
其次介绍了类与对象之间的关系,包括类的定义、对象的创建与使用、对象的引用传递和访问控制;
接着介绍了类的封装,包括为什么要封装以及如何实现封装;
接着介绍了构造方法,包括构造方法的定义与重载;
然后介绍了this关键字的使用,包括使用this关键字调用本类中的属性、成员变量和构造方法;
最后介绍了代码块的使用以及static关键字的使用。

(1)包名中所有字母小写

(2)类名和接口名的每个首字母都大写,ArrayList

(3)常量名中所有字母都大写,单词之间用下画线连接,DAY_OF_MONTH

(4)变量名和方法名的第一个单词首字母小写,从第二个单词开始每个单词首字母大写,lineNumber,getLineNumber

(5)在程序中,尽量使用有意义的英文单词定义标识符,使程序便于阅读,userName定义用户,password定义密码

标签:Java,name,构造方法,--,age,面向对象,Student,public,String
From: https://blog.csdn.net/m0_73678713/article/details/137176498

相关文章

  • 简单的OCR光学字符识别(可用于毕业设计)
    OCR作用就是提取图片中的文本转化成文本形式,主要分为两个部分,第一个部分:检测文字所在的位置,第二个部分:识别文本区域内容。代码简介其中test_images用于存放你想要识别的图像test_result用于存放识别的结果结果展示三张图分别为,需要识别的图片,识别图片的准确率,以及识别......
  • 32-3 APP渗透核心 - APP数据包抓取
    环境准备安装模拟器:在PC上安装一个Android模拟器,例如Genymotion、Bluestacks或者AndroidStudio提供的模拟器等。模拟器可以模拟手机环境,让你在PC上运行Android应用程序。下载APP:在模拟器中下载需要进行渗透测试的APP。你可以通过GooglePlay商店、APK文件或者其他渠道获......
  • 实时数仓项目《二》-利用chatgpt prompt完成基础维表的创建
    系列文章:实时数仓项目《一》-实时数仓架构-CSDN博客目录5.ods->dwd:维表关联方案及维表加工、导入hbase5.1维表关联方案5.2退维后结果去向5.3创建维表:基础业务库表数据同步到hbase5.3.1cdc读取mysql数据,生成临时映射表5.3.2将目标表映射到Hbase中,生成临时映射......
  • 2024.2.7力扣每日一题——二叉树的堂兄弟节点2
    2024.2.7题目来源我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)方法二广度优先遍历(官方题解,在上一层求下一层)题目来源力扣每日一题;题序:2461我的题解方法一哈希表+层序遍历(自己的想法,硬在每一层去算)使用两个哈希表分别映射parent<子节点,父节点>,c......
  • 2024.2.8力扣每日一题——二叉树的堂兄弟节点
    2024.2.8题目来源我的题解方法一层序遍历方法二深度优先遍历题目来源力扣每日一题;题序:993我的题解方法一层序遍历使用层序遍历,先判断x或y是否是根节点,若是则x和y必然不可能是堂兄弟节点。每次遍历当前层时判断下一层是否出现x和y,若x和y分别出现在该节点的......
  • ctf题目
    目录1.文件包含的一道题目,没什么难度,2.一道sql注入的题目,伪静态3.限制只能本地访问。1.文件包含的一道题目,没什么难度,但是一个点就是它这里去包含的那个文件名就是flag,而不是flag.php也不是flag.txt,这样创建文件也是可以的,虽然没有后缀名,但是php的网站在进行文件包含的......
  • rainy75 键盘设置手册
    蓝牙配对显示电量切换模式(win/mac)Fn组合按键......
  • C语言----预处理(详解)
         好了书接上回。我在讲编译与链接的时候写过宏和条件建议。我说会在下一篇博客中讲解,那么来了。今天我们来详细的讲讲预处理。宏与条件编译也在其中,那么我们现在就来好好会会这个预处理吧。预定义符号    关于预定义符号,我暂时只知道几个。并且我知道的......
  • C语言----简单讲解编译与链接
        大家好,这次我们来讲讲我们写下代码后,源代码是变为执行文件的,这里我们将会使用用另外一种编译器(gcc),但是嘞因为鄙人对电脑的理解还是比较少的,所以对于我们进行对比的编译器(gcc)鄙人只能提供代码,以及一些网络上其他博主的图文,希望大家理解这样更加方便大家了解。(如果大......
  • NewStarCTF(Reserve) WEEK1
    easy_RE咳有UPX壳,先脱壳enc="gmbh|D1ohsbuv2bu21ot1oQb332ohUifG2stuQ[HBMBYZ2fwf2~"flag=''foriinenc:b=(ord(i)-1)flag+=chr(b)print(flag)#flag{C0ngratu1at10ns0nPa221ngTheF1rstPZGALAXY1eve1}Segmentssegments用sh......