Java开发零基础篇:day10 面向对象(四)

简介: 面向对象

 this关键字(二)

this 回顾

观察代码

public class Dog { 
    String sn; 
    String name; 
    int age;
    public Dog(){}
    public Dog(String s,String n,int a){ 
        sn = s;
        name = n; 
        age = a;
    }
    public void sayHi(){ 
        System.out.println("我的名字:"+ name); 
        System.out.println("我的年龄:" + age);
    }
}

image.gif

以上代码存在什么问题?

前面什么地方用到this?this到底是什么呢?

this主要存在于两个位置:

在构造器中:表示当前被创建的对象

在方法中:哪一个对象调用this所在的方法,此时this就表示哪一个对象

优化后:

/**
* 满足封装概念的Dog
*/
public class Dog { 
    private String sn; 
    private String name; 
    private int age;
    public void setSn(String sn) { 
        this.sn = sn;
    }
    public String getSn() { 
        return sn;
    }
    public void setName(String name) { 
        this.name = name;
    }
    public String getName() { 
        return name;
    }
    public void setAge(int age) { 
        this.age = age;
    }
    public int getAge() { 
        return age;
    }
    public Dog(String sn, String name, int age) { 
        this.sn = sn;
        this.name = name; 
        this.age = age;
    }
    public Dog() {}
}

image.gif

this 内存图

image.gif编辑

this关键字表示当前对象本身,一般用于类的内部,其内部存在一个地址,指向当前初始化的对象本身。

public class Test01 {
    public static void main(String[] args) { 
        Dog dog = new Dog(" 旺 财 ", 20); 
        System.out.println("dog = " + dog);
    }
}

image.gif

当new一个对象时,实际上产生了两个引用,一个是供类Dog内部调用其成员变量和成员方法的this关键字,一个是供外界程序调用实例成员的dog。

this 三种用法

(1)调用成员变量

解决局部变量和成员变量之间的二义性,此时必须使用

调用其他实例方法

同一个类中非static方法间互调(此时可以省略this,但是不建议省略)

public void sayHi(){
    // System.out.println("大家好,我叫"+this.name+",我今年"+this.age+"岁");
    System.out.println("我的自白:"); this.showInfo();
}

image.gif

(3)调用本类其他构造方法

this可以调用本类其他构造方法,语法

this(); 
this(,,,);

image.gif

注意 : 在构造方法中调用本类其他构造方法必须写到该构造方法第一句,否则出现编译错误。

image.gif编辑

一个结合this,满足封装的实战中的Dog类。

/**
* 满足封装概念的Dog
*/
public class Dog { 
    private String sn; 
    private String name; 
    private int age;
    public void setSn(String sn) { 
        this.sn = sn;
    }
    public String getSn() { return sn;
    }
    public void setName(String name) { 
        this.name = name;
    }
    public String getName() { 
        return name;
    }
    public void setAge(int age) { 
        this.age = age;
    }
    public int getAge() { 
        return age;
    }
    public Dog(String sn, String name, int age) {
        //this.sn = sn;
        // this.name = name;
        this(sn,name); 
        this.age = age;
    }
    public Dog(String sn,String name){ 
        this.sn = sn;
        this.name = name;
    }
    public Dog() {}
    public void sayHi(){
        // System.out.println("大家好,我叫"+this.name+",我今年"+this.age+"岁");
        this.showInfo();
    }
    public void showInfo(){ 
        System.out.println("我的自白:");
        System.out.println("我的名字:" + this.name);
        System.out.println("我的年龄:" + this.age);
    }
}

image.gif

super关键字(二)

回顾 super

回顾之前什么时候使用super:

在子类方法中,调用父类被覆盖的方法,此时必须使用super。

super 关键字

super 关键字表示父类对象,子类要访问父类成员时可以使用super。

super只是一个关键字,内部没有引用(地址)。

super 访问父类非私有字段

System.out.println("我的名字" + super.nick); 
System.out.println("我的健康值" + super.health);
System.out.println("我的亲密度" + super.love); 
System.out.println("我是一只" + this.strain);

image.gif

super 访问父类非私有方法

super.print();
System.out.println("我是一只" + this.strain);

image.gif

super 访问父类构造方法

语法: 
super(); 
super(,,,);

image.gif

例子:


public class Dog extends Pet { 
    String strain;
    public Dog(String nick,int health,int love,String strain){ 
        super(nick,health,love);
        this.strain = strain;
    }
    、、、、
}

image.gif

总结:

super 调用构造方法必须写在子类构造方法的第一句;

如果子类构造方法没有显式调用父类构造方法时,那么jvm会默认调用父类的无参构造super()。

static修饰符

问一个生产车的工厂,一共生产了多少量车?

=> 构成一个车(Car) 的类,统计Car一共创建了多少对象?

=> 紧接着继续思考:统计Car创建了多少对象是不是需要一个变量totalCount?

=> 紧接着继续思考:在哪里声明这个变量totalCount呢?

static

static 关键字表示静态,可以修饰变量构成静态变量,修饰方法构成静态方法。静态变量和静态方法都归类所有,称为类的静态成员,用static关键字修饰。

静态变量

在类中,用static关键字修饰的成员变量称为静态变量,归类所有,也称为类变量,类的所有实例/对象都可以访问,被类的所有实例或对象所共享。

语法 :

static 数据类型 成员变量 [=初始值];

image.gif

静态变量的访问

类名.静态变量(推荐写法) 
对象/实例.静态变量

image.gif

Car创建了多少量车?

public class Car{
    String brand; 
    String type; 
    float price;
    // 静态变量,归类所有
    static int count = 0;
    public Car(){
        //Car.count++; 
        this.count++;
    }
    public Car(String brand,String type,float price){ 
        this.brand = brand;
        this.type = type; 
        this.price = price;
        // Car.count++; 
        this.count++;
    }
    、、、、
}

image.gif

类变量/静态变量被类的所有实例或对象所共享

静态方法

static 也可以修饰方法称为静态方法,归类所有,也称类方法。

语法

[修饰符] static 返回值类型 方法名(形参列表){
}

image.gif

静态方法访问方式

类名.静态方法()
对象.静态方法()

image.gif

静态方法特性

静态方法中可以访问静态变量和类的其他静态方法

实例方法中可以访问静态成员(静态变量和静态方法);静态方法不能访问实例成员

public class Car {
    static int num = 0;
    public Car(){
        Car.num++;
        //num++; <==>  this.num++;
        //this.num++;
    }
    public static void test(){ 
        System.out.println("test");
    }
    public static int getNum(){
        // System.out.println(this.count);
        // this.showInfo();
        Car.test();
        return Car.num;
    }
    public void showInfo(){
        // 访问静态变量
        // System.out.println(Car.num);
        // 访问静态方法
        Car.getNum();
    }
}

image.gif

jvm加载 static 成员的过程

当加载一个类到jvm的静态区时,首先jvm会扫描xx.class中的静态成员并分配空间且初始化。

当通过xx.class new一个对象时,可以在该对象的实例方法中访问静态成员;反之静态方法中不能访问实例成员。

image.gif编辑

final修饰符

final 表示最终的意思,可以修饰类、方法、局部变量、成员变量。

最终类

final 修饰类表示最终类。

public final class Car extends MotoVehicle {
}

image.gif

最终类不能被继承。

最终方法

如果一个方法被final修饰,称为最终方法。

public final void test() { 
    System.out.println("test");
}

image.gif

最终方法不能被重写。

常量

final修饰的局部变量称为常量,常量只能赋值一次,不能再重新赋值。

基本数据类型:表示的值不能改变

引用数据类型:所引用的地址值不能改变

(1)final修饰基本数据类型

final int a = 10;
// error
// a = 20

image.gif

(2)final修饰引用数据类型

// 常引用
// final 修饰引用数据类型
final Car car = new Car(); 
System.out.println(car); 
car.setBrand("Benz"); 
car.setType("X5");
car.setBrand("Audi"); 
car.setBrand("A4");
// car 被final修饰,不能再用于指向其他堆空间
//car = new Car();
//System.out.println(car);

image.gif

代码块

{} 标记的代码称为代码块,根据其位置的不同可以分为普通代码块、构造代码块、静态代码块、同步代码块。

普通代码块

普通代码块{},一般存在于方法中,形成作用域。

作用域特性:

作用域可以嵌套,内层作用作用域可以访问外层作用域的变量

当访问一个变量时,首先在变量所在的作用域查找,如果能找到,停止查找并输出变量内容;当本 作用域没找到时,尝试去上一次作用域查找,依次类推。这个过程形成的查找链称为作用域链。

public class Dog {
    String nick; 
    int health; 
    int love; 
    String strain;
    int count0 = 0;
    public void showInfo(){
        int count1 = 10;
        // 普通代码块
        {
            // int count1 = 100; int count2 = 20;
            System.out.println(count2); System.out.println(count1);
            // System.out.println(count0);
            System.out.println(this.count0);
        }
    }
    、、、
}

image.gif

构造代码块

构造代码块在类中(类的内部)、方法外。

构造代码块构造一个对象执行一次,在构造方法前执行

public class Car{
    private String brand; 
    private String type; 
    private float price;
    // 构造代码块
    {
        System.out.println("构造代码块...");
    }
    public Car(){}
    public Car(String brand,String type,float price{
        System.out.println("Car(String,String,float)"); 
        this.brand = brand;
        this.type = type;
        this.price = price;
     }
}

image.gif

如果需要在构造方法执行前加载一些资源(读取配置文件、xml文件等)时使用。我们把构造对象前的 一切操作都可以放到构造代码块中去执行。

静态代码块

被static关键字修饰的代码块称为静态代码块。 静态代码块位于类的内部、方法的外部。

静态代码块只执行一次,在构造代码块、构造方法前执行。

当类的字节码被加载到内存时,此时程序需要加载一些资源(读取资源文件等),可以使用静态代码块, 此时被加载进来的资源一般都可以被多个实例所共享。

内部类

public class Car{ 
    String brand;
    String type; float price;
    static int count;
    // 静态代码块
    static{
        System.out.println("静态代码块..."); count = 0;
    }
    // 构造代码块
    {
        System.out.println("构造代码块...");
    }
    public Car(){}
    public Car(String brand,String type,float price){
        System.out.println("Car(String,String,float)"); 
        this.brand = brand;
        this.type = type; this.price = price;
    }
}

image.gif

类的组织方式

(1)类和类之间平行关系

一个文件可以定义多个类,但只能存在一个public类,且文件的名字和public类的名字保持一致。

public class Dog {
}
class Penguin{
}

image.gif

编译完成后

Dog和Penguin 地位一样,和分开定义成两个文件一样。

image.gif编辑

(2)类和类之间包含关系

public class Outer { 
    public class Inner{
    }
}

image.gif

编译完成后

image.gif编辑

Outer和Inner是包含关系。Outer称为外部类,Inner称为内部类。

内部类Inner作为一个Outer的成员而存在。

内部类概述

什么是内部类,把一个类定义在另一个类的内部,把里面的类称之为内部类,把外面的类称之为外部类。

image.gif编辑

内部类可以看作和字段、方法一样,是外部类的成员,而成员可以有static修饰。

静态内部类:使用static修饰的内部类,那么访问内部类直接使用外部类名来访问

实例(成员)内部类:没有使用static修饰的内部类,访问内部类使用外部类的对象来访问

局部(方法)内部类:定义在方法中的内部类,一般不用

匿名内部类:特殊的局部内部类,适合于仅使用一次使用的类

对于每个内部类来说,Java编译器会生成独立.class文件。

静态和实例内部类:外部类名$内部类名字

局部内部类:外部类名$数字内部类名称

匿名内部类:外部类名$数字

成员内部类

内部类Inner作为外部类的一个成员而存在,Inner称为成员内部类。

public class Outer {
    [修饰符] class Inner{
    }
}

image.gif

一般而言,成员内部类的访问修饰符是默认访问权限(包访问权限),开发时,可以根据需要添加具体的访问权限。

创建成员内部类对象

public class Test01 {
    public static void main(String[] args) {
        // [1] 创建外部类对象
        Outer outer = new Outer();
        // [2] 创建内部类对象
        Outer.Inner inner = outer.new Inner(); 
        inner.showInfo();
    }
}

image.gif

成员内部类特性

成员内部类可以直接访问外部类的私有成员

public class Outer {
    private String name = "Outer";
    class Inner{
        public void showInfo() { 
            System.out.println("inner:showInfo()");
            // [1]访问外部类的私有成员System.out.println(name);
        }
    }
}

image.gif

静态内部类

成员内部类如果被static修饰变成静态内部类,作为外部类的一个静态成员而存在。

public class Outer {
    static class Inner{
    }
}

image.gif

创建静态内部类对象

public class Test01 {
    public static void main(String[] args) {
        // 1.创建静态内部类对象
        Outer.Inner inner = new Outer.Inner(); 
        inner.showInfo();
    }
}

image.gif

静态内部类特性

静态内部类可以访问外部类的静态私有成员

public class Outer {
    private static String name = "Outer";
    static class Inner{
        public void showInfo() { 
            System.out.println("static inner:showInfo()");
            System.out.println(name);
        }
    }
}

image.gif

方法内部类

当一个类存在于方法中时,构成方法内部类。方法内部类只能存在于方法中,同时也只能在方法中创建对象,

方法内部类前没有任何修饰符,因为内部类定义在方法中,都是局部存在的。

方法内部类特性

方法内部类可以读取方法的局部变量,但不能修改。

public class Outer {
    public void print(int count) {
        int a = 10;
        class Inner{
            public void showInfo() { 
                System.out.println("print():showInfo()");
                // System.out.println(a);
                // System.out.println(count);
                // 方法中的局部变量只能读,不能被方法内部类修改
                // count = 1000;
        }
    }
        // 只要在showInfo访问了a或者count,a和count就被加final修饰,在方法内部类外都不能
        a = 20;
        count = 1000;
        // 创建方法内部类对象
        //Inner inner = new Inner();
        //inner.showInfo();
        // 匿名对象
        new Inner().showInfo();
    }
}

image.gif

匿名内部类

当一个类只使用一次,可以声明成匿名内部类匿名内部类 必须有实现存在。

public class Outer {
    public void print(){
        /*
        class Inner implements AInterface{
            @Override
            public void showInfo() { 
                System.out.println("inner.showInfo");
            }
       }
        new Inner().showInfo();
        */
        /*AInterface aInterface = new AInterface(){
            @Override
            public void showInfo() { 
                System.out.println("inner.showInfo");
            }
        };
        aInterface.showInfo();*/
    // 通过匿名类创建匿名对象
    new AInterface(){
        @Override
        public void showInfo() { 
            System.out.println("inner.showInfo");
        }
    }
}

image.gif

枚举类

枚举的诞生史

在服装行业,衣服的分类根据性别可以表示为三种情况:男装、女装、中性服装。

private ?   type;
public void setType(? type){ 
    this.type = type
}

image.gif

定义一个变量来表示服装的分类?请问该变量的类型使用什么?

使用int和String类型,且先假设使用int类型,因为分类情况是固定的,为了防止调用者乱创建类型,可以把三种情况使用常量来表示。

public class ClothType {
    public static final int MEN = 0; 
    public static final int WOMEN = 1; 
    public static final int NEUTRAL = 2;
}

image.gif

注意:

常量使用final修饰,并且使用大写字母组成,如果是多个单词组成,使用下划线分割。

此时调用setType方法传递的值应该是ClothType类中三个常量之一。但是此时依然存在一个问题

——依然可以乱传入参数比如100,此时就不合理了。

同理如果使用String类型,还是可以乱设置数据。那么说明使用int或String是类型不安全的。那么如果使用对象来表示三种情况呢?

public class ClothType {
    public static final ClothType MEN = new ClothType(); 
    public static final ClothType WOMEN = new ClothType(); 
    public static final ClothType NEUTRAL = new ClothType();
}

image.gif

此时调用setType确实只能传入ClothType类型的对象,但是依然不安全,为什么?因为调用者可以自行创建一个ClothType对象,如:setType(new ClothType())。

此时为了防止调用者私自创建出新的对象,我们把CLothType的构造器私有化起来,外界就访问不了了,此时调用setType方法只能传入ClothType类中的三个常量。此时代码变成:

public class ClothType {
    public static final ClothType MEN = new ClothType(); 
    public static final ClothType WOMEN = new ClothType();
    public static final ClothType NEUTRAL = new ClothType(); 
    private ClothType() {}
}

image.gif

高,实在是高!就是代码复杂了点,如果存在定义这种类型安全的且对象数量固定的类的语法,再简单点就更好了——有枚举类。

枚举类的定义和使用

枚举是一种特殊的类,固定的一个类只能有哪些对象,定义格式:

public enum 枚举类名{ 
    常量对象A,
    常量对象B, 
    常量对象C;
}

image.gif

我们自定义的枚举类在底层都是直接继承了java.lang.Enum类的。

public enum ClothType { 
    MEN, WOMEN, NEUTRAL;
}

image.gif

枚举中都是全局公共的静态常量,可以直接使用枚举类名调用。

ClothType type = ClothType.MEN;

image.gif

因为java.lang.Enum类是所有枚举类的父类,所以所有的枚举对象可以调用Enum类中的方法.

String  name = 枚举对象.name(); //  返回枚举对象的常量名称
int ordinal = 枚举对象.ordinal();   //  返回枚举对象的序号,从0开始

image.gif

int ordinal = 枚举对象.ordinal(); // 返回枚举对象的序号,从0开始

注意:枚举类不能使用创建对象

public class EnumDemo {
    public static void main(String[] args) { 
        int ordinal = ClothType.MEN.ordinal(); 
        String name = ClothType.MEN.name(); 
        System.out.println(ordinal); 
        System.out.println(name);
        new ClothType();    //语法报错
    }
}

image.gif

以上就是Java入门第十天的全部内容了。

资料文档地址:Java开发零基础篇:day10面向对象(四).pdf

相关文章:Java开发零基础篇:day06 面向对象(一)

                 Java开发零基础篇:day08 面向对象(二)

                 Java开发零基础篇:day09 面向对象(三)

目录
相关文章
|
1月前
|
Java API Maven
如何使用Java开发抖音API接口?
在数字化时代,社交媒体平台如抖音成为生活的重要部分。本文详细介绍了如何用Java开发抖音API接口,从创建开发者账号、申请API权限、准备开发环境,到编写代码、测试运行及注意事项,全面覆盖了整个开发流程。
104 10
|
28天前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
18天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
37 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
5天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
47 13
|
10天前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
43 10
|
3天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
38 2
|
13天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
14天前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
19 1
|
29天前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
40 2
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。