最新Java基础系列课程--Day07-面向对象的特性(一)

本文涉及的产品
访问控制,不限时长
简介: 最新Java基础系列课程--Day07-面向对象的特性

各位同学,接下来的二天课程中,我们继续学习面向对象的相关课程。面向对象是写Java程序的核心套路,如何你不懂面向对象,那就相当于Java你白学了。所以在接下来的二天时间里,各位同学也需要克服重重困难好好学习。

前面我们说过面向对象最核心的套路是:设计对象来处理数据,解决问题。 如果你把面向对象高级这一部分课程学好,你设计出来的对象将更加好用。

在正式学习面向对象高级课程之前,我给大家提一些学习上的建议。目前我们学习的面向对象高级部分的知识点,就像一个一个的螺丝钉,在学习过程中你可能并不知道这些螺丝钉是用在哪里的,解决的什么问题。必须等这些内容都学习完之后,才能知道用这些螺丝钉可以用来搞飞机、造航母、造火箭。

所以,现阶段我们在学习过程中,主要关注下面几点就可以了。等整个基础课程学习完之后,再慢慢感在到哪里用。

一,类的私有成员和公共成员

1.1 私有成员

类的成员声明前加上私有访问控制符private,则成员只能被该类自身访问和修改,而不能被其他类(包括该类的子类)访问。达到了对数据最高级别保护的目的。

示例:

public class demo{
   private int age = 100;
   public int getAge(){
      return age;  //可以在类的内部方法中使用private成员,但外部类不可以
   }
}

那么外部类怎么访问一个类的内部私有成员呢?比如上个示例中,可以通过公有的成中方法来访问私有的成中属性。如果一个方法被声明为私有的,则不可以被外部类访问调用。

1.2 公共成员

类的成员声明前加上公共访问控制符public,则表示该成员可以被其他类所访问。造成安全性和数据封装性的下降,所以一般减少该成员的使用。

public class Demo{
   private int age = 100;
   public String name = "sisa";
   public int getAge(){
      return age;  //可以在类的内部方法中使用private成员,但外部类不可以
   }
}

上述示例中:name属性为公有的,getAge()方法为公有的,可以被外部类来访问

public class Demo01{
   public static void main(String[] args){
        Demo demo = new Demo();
        demo.name = "sisa2023";
        int age = demo.getAge();
   }
}

1.3 缺省访问控制符

若在类成员的前面不加任何访问控制符,则该成员具有缺省的访问控制特性。

缺省访问控制权,表示这个成员只能被同一个包(类库)中的类所访问和调用,如果一个子类与父类位于不同的包中,子类也不能访问父类中的缺省访问控制成员,也就是说其他包中的任何类都不能访问缺省访问控制成员。

同理,对于类来说,如果一个类没有访问控制符,说明它具有缺省访问控制特性。

二、静态

接下来,我们学习一下面向对象编程中很常见的一个关键字static.

static读作静态,可以用来修饰成员变量,也能修饰成员方法。我们先来学习static修饰成员变量。

1.1 static修饰成员变量

Java中的成员变量按照有无static修饰分为两种:类变量、实例变量。它们的区别如下图所示:

由于静态变量是属于类的,只需要通过类名就可以调用:类名.静态变量

实例变量是属于对象的,需要通过对象才能调用:对象.实例变量

  • 下面是代码演示(注意静态变量,和实例变量是如何调用的)

为了让大家对于这两种成员变量的执行过程理解更清楚一点,在这里给大家在啰嗦几句,我们来看一下上面代码的内存原理。

  • 最后总结一下
- 1.类变量:属于类,在内存中只有一份,用类名调用
- 2.实例变量:属于对象,每一个对象都有一份,用对象调用

1.2 static修饰成员变量的应用场景

学习完static修饰成员变量的基本使用之后,接下来我们学习一下static修饰成员变量在实际工作中的应用。

在实际开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住。

我们看一个案例**

需求:系统启动后,要求用于类可以记住自己创建了多少个用户对象。**

  • 第一步:先定义一个User类,在用户类中定义一个static修饰的变量,用来表示在线人数;
public class User{
    public static int number;
    //每次创建对象时,number自增一下
    public User(){
        User.number++;
    }
}
  • 第二步:再写一个测试类,再测试类中创建4个User对象,再打印number的值,观察number的值是否再自增。
public class Test{
    public static void main(String[] args){
        //创建4个对象
        new User();
        new User();
        new User();
        new User(); 
        //查看系统创建了多少个User对象
        System.out.println("系统创建的User对象个数:"+User.number);
    }
}

运行上面的代码,查看执行结果是:系统创建的User对象个数:4

1.3 static修饰成员方法

各位同学,学习完static修饰成员变量之后,接下来我们学习static修饰成员方法。成员方法根据有无static也分为两类:类方法、实例方法

有static修饰的方法,是属于类的,称为类方法;调用时直接用类名调用即可。

无static修饰的方法,是属于对象的,称为实例方法;调用时,需要使用对象调用。

我们看一个案例,演示类方法、实例方法的基本使用

  • 先定义一个Student类,在类中定义一个类方法、定义一个实例方法
public class Student{
    double score;
    //类方法:
    public static void printHelloWorld{
        System.out.println("Hello World!");
        System.out.println("Hello World!");
    }
    //实例方法(对象的方法)
    public void printPass(){
        //打印成绩是否合格
        System.out.println(score>=60?"成绩合格":"成绩不合格");
    }
}
  • 在定义一个测试类,注意类方法、对象方法调用的区别
public class Test2{
    public static void main(String[] args){
        //1.调用Student类中的类方法
        Student.printHelloWorld();
        //2.调用Student类中的实例方法
        Student s = new Student();        
        s.printPass();
        //使用对象也能调用类方法【不推荐,IDEA连提示都不给你,你就别这么用了】
        s.printHelloWorld();
    }
}

搞清楚类方法和实例方法如何调用之后,接下来再啰嗦几句,和同学们聊一聊static修饰成员方法的内存原理。

1.类方法:static修饰的方法,可以被类名调用,是因为它是随着类的加载而加载的;
     所以类名直接就可以找到static修饰的方法
2.实例方法:非static修饰的方法,需要创建对象后才能调用,是因为实例方法中可能会访问实      例变量,而实例变量需要创建对象后才存在。
      所以实例方法,必须创建对象后才能调用。

关于static修饰成员变量、和静态修饰成员方法这两种用法,到这里就学习完了。

1.4 工具类

学习完static修饰方法之后,我们讲一个有关类方法的应用知识,叫做工具类。

如果一个类中的方法全都是静态的,那么这个类中的方法就全都可以被类名直接调用,由于调用起来非常方便,就像一个工具一下,所以把这样的类就叫做工具类。

  • 我们写一个生成验证码的工具类
public class MyUtils{
    public static String createCode(int n){
        //1.定义一个字符串,用来记录产生的验证码
        String code = "";
        //2.验证码是由所有的大写字母、小写字母或者数字字符组成
        //这里先把所有的字符写成一个字符串,一会从字符串中随机找字符
        String data = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ";
        //3.循环n次,产生n个索引,再通过索引获取字符
        Random r = new Random();
        for(int i=0; i<n; i++){
            int index = r.nextInt(data.length());
            char ch = data.charAt(index);
            //4.把获取到的字符,拼接到code验证码字符串上。
            code+=ch;
        }
        //最后返回code,code的值就是验证码
        return code;
    }
}
  • 接着可以在任何位置调用MyUtilscreateCOde()方法产生任意个数的验证码
//比如这是一个登录界面
public class LoginDemo{
    public static void main(String[] args){
        System.out.println(MyUtils.createCode());
    }
}
//比如这是一个注册界面
public class registerDemo{
    public static void main(String[] args){
        System.out.println(MyUtils.createCode());
    }
}

工具类的使用就是这样子的,学会了吗?

在补充一点,工具类里的方法全都是静态的,推荐用类名调用为了防止使用者用对象调用。我们可以把工具类的构造方法私有化。

public class MyUtils{
    //私有化构造方法:这样别人就不能使用构造方法new对象了
    private MyUtils(){
    }
    //类方法
    public static String createCode(int n){
       ...
    }
}

1.5 static的注意事项

各位同学,到现在在我们已经学会了static修饰的变量、方法如何调用了。但是有一些注意事项还是需要给大家说明一下,目的是让大家知道,使用static写代码时,如果出错了,要知道为什么错、如何改正。

public class Student {
    static String schoolName; // 类变量
    double score; // 实例变量
    // 1、类方法中可以直接访问类的成员,不可以直接访问实例成员。
    public static void printHelloWorld(){
        // 注意:同一个类中,访问类成员,可以省略类名不写。
        schoolName = "DTS";
        printHelloWorld2();
        System.out.println(score); // 报错的
        printPass(); // 报错的
        ystem.out.println(this); // 报错的
    }
  // 类方法
    public static void printHelloWorld2(){
    }
    // 实例方法
    public void printPass2(){
    }
    // 实例方法
    // 2、实例方法中既可以直接访问类成员,也可以直接访问实例成员。
    // 3、实例方法中可以出现this关键字,类方法中不可以出现this关键字的
    public void printPass(){
        schoolName = "sisa2"; //对的
        printHelloWorld2(); //对的
        System.out.println(score); //对的
        printPass2(); //对的
        System.out.println(this); //对的
    }
}

1.6 static应用(代码块)

各位同学,接下来我们再补充讲解一个知识点,叫代码块;代码块根据有无static修饰分为两种:静态代码块、实例代码块

我们先类学习静态代码块:

public class Student {
    static int number = 80;
    static String schoolName = "sisa";
    // 静态代码块
    static {
        System.out.println("静态代码块执行了~~");
        schoolName = "sisa";
    }
}

静态代码块不需要创建对象就能够执行

public class Test {
    public static void main(String[] args) {
        // 目标:认识两种代码块,了解他们的特点和基本作用。
        System.out.println(Student.number);
        System.out.println(Student.number);
        System.out.println(Student.number);
        System.out.println(Student.schoolName); // sisa
    }
}

执行上面代码时,发现没有创建对象,静态代码块就已经执行了。

关于静态代码块重点注意:静态代码块,随着类的加载而执行,而且只执行一次。

再来学习一下实例代码块

实例代码块的作用和构造器的作用是一样的,用来给对象初始化值;而且每次创建对象之前都会先执行实例代码块。

public class Student{
    //实例变量
  int age;
    //实例代码块:实例代码块会执行在每一个构造方法之前
    {
        System.out.println("实例代码块执行了~~");
        age = 18;
        System.out.println("有人创建了对象:" + this);
    }
    public Student(){
        System.out.println("无参数构造器执行了~~");
    }
    public Student(String name){
        System.out.println("有参数构造器执行了~~");
    }
}

接下来在测试类中进行测试,观察创建对象时,实例代码块是否先执行了。

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student("张三");
        System.out.println(s1.age);
        System.out.println(s2.age);
    }
}

对于实例代码块重点注意:实例代码块每次创建对象之前都会执行一次

三、构造方法和重载

3.1 构造方法

构造方法(constructor)是一种特殊的方法,它是在对象被创建时初始化对象的成员的方法,也称为构造器。它有如下特点。

1、构造方法的方法名与类名相同。

2、构造方法没有返回值,也不能有void。

3、构造方法的主要作用是对类对象的初始化工作。

4、构造方法一般不能由编程人员显式地直接调用,而是用new来调用。

5、在创建一个类的对象的同时,系统会自动调用该类的构造方法为新的对象初始化。

6、可带参数,还可以完成赋值之外的其他复杂操作

如果省略构造方法,Java编译器会自动为该类生成一个默认的构造方法,程序在创建对象时会自动调用默认的构造方法。默认的构造方法没有参数,在其方法体中也没有任何代码,即什么也不做。若class前面有public修饰符,则默认的构造方法前面也是public。一旦用户为某类定义了构造方法,系统就不再提供默认的构造方法,这是Java的覆盖所致。

关于构造器在第4章己讲述。

3.3 方法重载

面向对象的三大特性之一:多态性:一个程序中同名的多个不同方法共存的情况。常用重载和覆盖(重写)。

方法的重载是实现“多态”的方法之一。

方法重载的特征:

1、方法的重载是指方法带有不同的参数,但使用相同的名字。

2、方法的参数不同则表示实现不同的功能,但功能相似。

所谓参数不同是指:参数个数不同、参数类型不同、参数的顺序不同。参数的名字不同不能说明是方法的重载。

3、方法的重载和返回值没有关系

示例:

int  add(int x, int y);
int  add(int x, int y, int z);
float  add(float f1, float f2);
float add(float f1, int y);
float add(int y, float f1);
float  add(int x, int y);
int add(int u, int v);

构造方法的重载:方法名相而参数不同

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

从某一构造方法内调用另一构造方法,必须通过关键字this来调用的,否则编译出错。

this关键字必须写在构造方法内的第一行位置。

public class Student{
    private int age;
    private String name;
    public Student(){
        System.out.println("空参构造方法");
    }
    public Student(int age,String name){
        this.Student();
        System.out.println("非空参构造方法");
    }
}

注意:

构造方法一般都是public,因为它们在创建对象时,是在类的外部被系统自动调用的。
构造函数若被声明为private,则无法在构造方法所在的类以外的地方被调用,但在该类的内部还是可以被调用。


最新Java基础系列课程--Day07-面向对象的特性(二)https://developer.aliyun.com/article/1423501

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
相关文章
|
2月前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
2月前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
101 6
|
2月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
35 1
|
3月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
36 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
3月前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
50 4
|
3月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
61 2
|
4月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
169 3
|
IDE Java 关系型数据库
Java14发布,16大新特性,代码更加简洁明快
Java14发布,16大新特性,代码更加简洁明快
338 0
Java14发布,16大新特性,代码更加简洁明快
|
2天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
33 14
|
5天前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
34 13

热门文章

最新文章