1.1.2 Java特性章 Class(类和封装)

构造方法

没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。

构造方法中,可以通过this调用其他构造方法来简化代码,但是构造方法中调用构造方法一定要在第一行(即this(…)必须是构造方法中第一条语句)

  public class Date {
      public int year;
      public int month;
      public int day;
  // 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
  // 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
  // 但是this(1900,1,1);必须是构造方法中第一条语句
      public Date() {
  //System.out.println(year); 注释取消掉,编译会失败
          this(1900, 1, 1);
  //this.year = 1900;
  //this.month = 1;
  //this.day = 1;
      }
  // 带有三个参数的构造方法
      public Date(int year, int month, int day) {
          this.year = year;
          this.month = month;
          this.day = day;
      }
  }

This指针

构造函数用This

万一构造函数的形参也有与类中的成员相同的变量则会造成冲突

public class Data {
    private int year;
    private int month;
    private int day;

    public Data(int year, int month, int day) {
        this.year = year;//这么写不会造成冲突和可读性
        this.month = month;
        this.day = day;
    }
    
    public void printDate(){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
}

初始化

java类似于c++一样,默认类型会规定一个初始化值(即便构造函数没初始化),而自定义类型会调用自定义类型的无参构造函数,如果没有则为nul

数据类型默认值
byte0
char‘\u0000’
short0
int0
long0L
booleanfalse
float0.0f
double0.0
reference(引用)null

可以在没构造之前就给出初始化(就地初始化)

public class Date {
    public int year = 1900;
    public int month = 1;
    public int day = 1;
    public Date() {
    }
}

封装

范围关键字

范围privatedefaultprotectedpublic
同一包中的同类可以可以可以可以
同一包中不同类可以可以可以
不同包中的子类(别的包中有当前包的父类)可以可以
不同包中的非子类可以

public:可以理解为一个人的外貌特征,谁都可以看得到

default: 对于自己家族中(同一个包中父类对子类)不是什么秘密,对于其他人来说就是隐私了

private:只有自己知道,其他人都不知道

封装的包

import java.util.Date; //引入util文件下的单个包
import java.util.*; //引入util文件下的所有包,*为通配符
mport static java.lang.Math.*; //可以使用import static导入包中静态的方法和字段。
//可以自定义包
//在文件的最上方加上一个 package 语句指定该代码在哪个包中.
//包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.yzy.demo1 ).

//比如路径com.yzy.demo1的包 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
//如果一个类没有 package 语句, 则该类被放到一个默认包中.入src

package com.yzy.demo1;//指明了包的位置
public class Date {
    public int year = 1900;
    public int month = 1;
    public int day = 1;
    public Date() {
    }
   
}

官方的包

  1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
  2. java.lang.reflect:java 反射编程包;
  3. java.net:进行网络编程开发包。
  4. java.sql:进行数据库开发的支持包。
  5. java.util:是java提供的工具程序包。(集合类等) 非常重要
  6. java.io:I/O编程开发包。

成员变量

static修饰成员变量

  1. 默认就有,不需要初始化对象,每个对象指向的static成员变量为同一个值
  1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
  3. 类变量存储在方法区当中
  4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)

static修饰成员方法

被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过 静态方法来访问的。

  1. 不属于某个具体的对象,是类方法
  2. 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
  3. 不能在静态方法中访问任何非静态成员变量

static成员变量初始化

静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性

用代码块初始化

用原地初始化

代码块

普通代码块

普通代码块:定义在方法中的代码块.

构造代码块

构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。

public class Student {
//实例成员变量
    private String name;
    private String gender;
    private int age;
    private double score;
    public Student() {
        System.out.println("I am Student init()!");
    }
//实例代码块
    {
        this.name = "yzy";
        this.age = 12;
        this.sex = "man";
        System.out.println("I am instance init()!");
    }
    public void show() {
        System.out.println("name: " + name + " age: " + age + " sex: " + sex);
    }
}
public class Main {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.show();
    }
}

静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

public class Student {
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom;
//实例代码块
    {
        this.name = "yzy";
        this.age = 12;
        this.gender = "man";
        System.out.println("I am instance init()!");
    }
// 静态代码块
    static {
        classRoom = "class306";
        System.out.println("I am static init()!");
    }
    public Student() {
        System.out.println("I am Student init()!");
    }
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();
    }
}

各类代码块在创建对象时的先后出现顺序

  1. 静态代码块先执行,并且只执行一次,在类加载阶段执行
  2. 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

内部类

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服 务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类。内部类也是封装的一种体现。(比如二叉树的节点会在二叉树这个类中写好)

public class OutClass {
    class InnerClass {
    }
}
// OutClass是外部类
// InnerClass是内部类

内部类分类

public class OutClass {
// 成员位置定义:未被static修饰 --->实例内部类
    public class InnerClass1 {
    }
// 成员位置定义:被static修饰 ---> 静态内部类
    static class InnerClass2 {
    }
    public void method() {
// 方法中也可以定义内部类 ---> 局部内部类:几乎不用
        class InnerClass5 {
        }
    }
}

实例内部类的创建

// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类

// 创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();


// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.methodInner();

1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受publicprivate等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名
称.this.同名成员 来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

静态内部类的创建

public class OutClass {
    private int a;
    static int b;
    public void methodA() {
        a = 10;
        System.out.println(a);
    }
    public static void methodB() {
        System.out.println(b);
    }
	// 静态内部类:被static修饰的成员内部类
    static class InnerClass {
        public void methodInner() {
			// 在内部类中只能访问外部类的静态成员
			// a = 100; // 编译失败,因为a不是类成员变量
            b = 200;
			// methodA(); // 编译失败,因为methodB()不是类成员方法
            methodB();
        }
    }
    public static void main(String[] args) {
		// 静态内部类对象创建 & 成员访问
        //静态内部类不能访问外部类的非静态东西
        //外部类的成员可以包含静态内部类的元素
        OutClass.InnerClass innerClass = new OutClass.InnerClass();//直接用类名来创建
        innerClass.methodInner();
    }
}

​ 只有子类的时候:

  1. 在静态内部类中只能访问外部类中的静态成员
  2. 创建静态内部类对象时,不需要先创建外部类对象

​ 子类和父类都存在的时候:

  1. 父类静态代码块优先于子类静态代码块执行,且是最早执行
  2. 父类实例代码块和父类构造方法紧接着执行
  3. 子类的实例代码块和子类构造方法紧接着再执行
  4. 第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

局部内部类

基本不用

匿名内部类

抽象类和接口或者一些方法的临时使用

匿名类继承一个父类:

class person{

    public void method(){
        System.out.println("父类方法");
    }
}

public class Anonymous_inner_class {
    public static void main(String[] args) {
        person p = new person(){
            @Override
            public void method() {
                System.out.println("重写父类方法");
            }
        };
        p.method();
    }
}

匿名类实现一个接口:

interface inter{
    void method();
}

public class Anonymous_inner_class2 {
    public static void main(String[] args) {
        
        //这里new一个inter接口的子类,但是又把子类向上转型了
        inter i = new inter() { //这里一定要()是new inter的一个子类,但这个子类没有名字,如果子类要传参要 <参数>()
            @Override
            public void method() { 
                System.out.println("匿名内部类。");
            }
        };
        i.method();
    }
}


匿名内部类实现排序

Integer []a={1,2,3,4,5};
//这里相当于new 一个类 implements Comparator<Integer>(); 而内容直接写在这个类下面的花括号
Arrays.sort(a,new Comparator<Integer>(){
    public int compare(Integer o1, Integer o2) {
        return o2-o1;
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ap0stoL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值