Java学习笔记:类与对象

类与对象

1 概念

1.1 类与对象的关系

类:抽象的,概念的,是自定义数据类型,可以定义类的各种程序变量(属性, 或称field,字段)和方法

对象:实际的,一个具体的实例

类是对象的模版,对象是类的一个个体,对应一个实例

1.2 类的定义
//定义

class ClassName{//class为定义类的关键字
    field;//属性
    method;//成员方法
}

//创建对象
//实例化:用类类型创建对象的过程,称为类的实例化,创建时使用关键字new
//1.直接创建
	ClassName objectName = new ClassName();
//2.先声明再创建
	ClassName objectName;
	objectName = new ClassName();

//访问属性
	objectName.field;
//访问方法
	objectName.method;
1.3 内存分配

栈:一般存放基本数据类型(局部变量)

堆:存放对象(类、数组等)

方法区:常量池(常量,比如字符串),类加载信息(属性信息、方法信息)

2 属性(成员变量)

属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(对象,数组等)

//示例:访问修饰符 属性类型 属性名
private int a;
//也可以直接赋值
private int a = 1
注意事项
  • 属性的定义类型可以为任意类型,包含基本类型或引用类型

  • 属性如果不赋值,则有默认值

3 成员方法

许多情况下,类中需要定义成员方法

3.1 成员方法的定义
访问修饰符 返回数据类型 方法名 (形参列表) {//方法体
    语句;
    return 返回值;
}
//形参列表和return语句非必需
3.2 方法的调用

定义的方法存放常量区

1)当程序执行到方法时,就会开辟一个独立的空间(栈空间),在空间内创建变量,方法的局部变量是独立的,不会互相影响

2)当方法执行完毕,或者执行道return语句时,就会返回至调用方法的语句

4)返回后,继续执行方法后面的代码

5)当main方法(栈)执行完毕,整个程序退出

注意事项
  • 访问修饰符控制方法使用的范围
    private,default(即不写),protected,public

  • 一个方法的返回值最多只能有一个(想返回多个值可以使用数组),返回数据类型可以为任意类型,包含基本类型或引用类型(数组、对象)

  • 如果方法要求有返回数据类型(即非void),则最后方法中的最后执行语句必须为return值(返回值的类型应与要求的一致)

  • 遵循驼峰命名法,见名知义(变量名小驼峰类名大驼峰)

4 作用域

  1. Java中主要的变量就是属性(成员变量)和局部变量
  2. 局部变量一般指在成员方法中定义的变量
  3. Java中全局变量(即属性)的作用域为整个类体,局部变量(除属性外的其他变量)的作用域为定义它的代码块中
  4. 全局变量(属性)可以不赋值直接使用,因为有默认值,局部变量必须赋值后才能使用,因为没有默认值
注意事项
  • 属性和局部变量可以重名,访问时遵循就近原则

  • 在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名

  • 属性生命周期较长,伴随着对象的创建而创建和销毁而销毁。局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁,即一次方法调用。

  • 作用域范围不同
    全局变量/属性:可以被本类或其他类使用(通过对象调用)
    局部变量:只能在本类中对应的方法中使用

  • 修饰符不同:全局变量/属性可以加修饰符,局部变量不可以加修饰符

5 构造方法(构造器)

构造方法允许在创建对象时,直接将对像的属性初始化

例:

//语法
class 类名{
    [修饰符] 方法名 (形参列表){
    方法体;
    }
 }

class Person{
    
    String name;
    int age = 90;
    
    Person(String n, int a){
        name = n;
        age = a;
    }
    Person p = new Person("小明", 20);
}
注意事项
  • 构造方法名要与类名相同

  • 构造方法没有返回值

  • 在创建对象时,系统自动调用该类的构造方法(只调用一次):若用户没有定义构造方法,系统调用默认的无参构造方法,否则调用定义的构造方法(此时默认构造方法被覆盖)

  • 一个类可以定义多个不同的构造器,即构造器重载

6 this 关键字

构造器的形参为了方便一般直接写成参数名。如下:

public class Test {
    public static void main(String[] args) {
        Person p = new Person("小明", 20, "翻斗花园");
    }
}

class Person{

    String name;
    int age;
    String address;

    public Person(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
    //构造器中的name,age,address基于就近原则编译器将其理解为局部变量,而不是属性
    //局部变量在Person构造方法外则无法作用,所以info无法有效输出目标的结果。

    public void info(){
        System.out.println(name + "\t" + age + "\t" + address);
    }

}

解决这个问题只需在构造方法中的局部变量前加关键字this

即:

public Person(String name, int age, String address;){
    this.name = name;
    this.age = age;
    this.address = adderss;
}

表示当前对象的属性 name 和 age,哪个对象调用,this 就代表哪个对象

注意事项
  • this关键字可以用来访问本类的属性、方法、构造器

  • this 用于区分当前类的属性和局部变量

  • 访问成员方法的语法:this.方法名(参数列表);

  • 访问构造器语法:this(参数列表);

注意只能在构造器中使用(this关键字的语句必须置于构造方法中的第一条语句)

  • this不能在类定义的外部使用,只能在类定义的方法中使用

  • this是成员方法的第一个隐藏参数

在上述代码中

    public void info(){
        System.out.println(name + "\t" + age + "\t" + address);
    }

在属性前加上this

    public void info(){
        System.out.println(this.name + "\t" + this.age + "\t" + this.address);
    }

调用该方法,两种写法运行结果均为

this运行结果

7 修饰符

Java提供四种访问控制修饰符号控制方法和属性(成员变量)的访问权限(范围)

1.public:公开级别,对外公开

2.protected:受保护级别,对子类和同一个包中的类公开

3.默认:没有修饰符号,向同一个包的类公开

4.private:私有级别,只有类本身可以访问,不对外公开

访问级别修饰符同类同包子类不同包
公开public
受保护protected×
默认××
私有private×××
注意事项
  • 修饰符可以用来修饰类中的属性,成员方法以及类
  • 子类可以重写父类中被protected修饰的方法,且可以放大可访问的权限,即改写成public,但不能将父类中的public修饰方法改为protected,即缩小访问的权限
  • 只有默认和public才能修饰类,并遵循上述访问权限的特点
  • 成员方法的访问规则和属性一致

8 包

包是Java实现面向对象的封装机制的一种体现,程序员可以建立包来实现对多个类的管理

包的作用

1.区分相同名字的类

2.当类很多时,可以很好的管理类

3.控制访问范围

基本语法
package name;
//1.package: 关键字,表示打包
//2.name: 表示包名
//规则:包名只能包含数字、字母、下划线、点,但不能用数字开头,不能是关键字或保留字
包的本质

实际上是创建不同的文件夹来保存类文件

注意事项

  • package 的作用是是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一条package
  • import指令,用于导入包,位置放在package的下面,在类定义前面,可以有多条且没有顺序要求

9 static 关键字

static关键字可以修饰成员变量,成员方法和代码块

static修饰成员变量

当static修饰成员变量时,该成员变量变为静态变量,静态变量可用于引用所有对象的公共属性。

class Person{

    String name;
    int age;
    String address;
    static int money = 100;//money为静态变量

    public Person(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
   
    public void info(){
        System.out.println(name + "\t" + age + "\t" + address + "\t" + money);
        money++;
    }

}

public class Test {
    public static void main(String[] args) {
        Person p = new Person("小明", 20, "翻斗花园");//实例化p对象,money此时为100
        p.info();//调用成员方法,money + 1,此时money = 101
        Person q = new Person("小王", 20, "翻斗花园");//实例化q对象,money此时为101
    }
}
static修饰成员方法

被static修饰的成员方法称静态成员方法,静态方法属于类,是类的方法,而不属于类的对象,不是某个具体对象的方法

  • 静态方法可无需实例化即可直接调用

  • 静态方法可以访问静态属性,即静态成员变量

  • 静态方法不能访问非静态成员和调用非静态方法

//以上述代码为例
public static void info(){//info()为static修饰的静态方法
        System.out.println(name + "\t" + age + "\t" + address + "\t" + money);
    //编译时报错,原因时除money外,其余三个变量为非静态成员
        money++;
    }

//修正后,可直接调用info()
public class Test {
    public static void main(String[] args) {
        Person.info();
    }
}
static修饰代码块

代码块{}前加static,即为静态代码块,一般用于初始化静态成员变量

class Person{
    //实例成员
    String name;
    int age;
    String address;
    //静态成员
    static int money;//money为静态变量

    //实例代码块
    {
        System.out.println("实例代码块运行");
        name = "小明";
        age = 20;
        address = "翻斗花园";
    }

    //静态代码块
    static {
        System.out.println("静态代码块运行");
        money = 1000;
    }

    public Person() {
        System.out.println("无参构造器运行");
    }

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

    public static void info1(){
        money++;
        System.out.println(money);
        System.out.println("静态方法调用");
    }

    public void info2(){
        //普通代码块
        {
            System.out.println("普通代码块运行");
            System.out.println(name + "\t" + age + "\t" + address + "\t" + money);
        }
        money++;
    }

}

public class Test {
    public static void main(String[] args) {
        System.out.println("============");
        Person p = new Person();
        System.out.println("============");
        Person.info1();
        System.out.println("============");
        p.info2();
    }
}

运行结果如下:

代码块运行结果

由运行结果可见,程序执行的顺序为先加载静态成员,执行静态代码块中的语句完成静态成员的初始化,再执行实例化代码块和构造方法中的语句,静态方法info1()和成员方法info2()中普通代码块则需待main中相应语句执行调用

10 内部类

内部类可以在类中的任意位置定义,内部类可分为三种:成员内部类、局部内部类、匿名内部类

成员内部类

成员内部类又可分为实例内部类和静态内部类

class Person{

    String name = "小明";
    int age;
    String address;
    static int money = 100;

    public Person(){
        //无参构造器
    }

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


    public void info1(){
        System.out.println("外部类实例方法");
    }

    public static void info2(){
        System.out.println("外部类静态方法");
    }

    //实例内部类
    class Student{
        String name = "学生";
        String id = "1234567";

        public void info3(){
            info1();
            info2();
            System.out.println("实例内部类方法");
            System.out.println("实例内部类属性:" + name + " " + id);
            System.out.println("外部类非静态属性:"+ age + 
            "\t外部类静态属性:" + money);
        }
    }

    //静态内部类
    static class teacher {
        String name = "老师";
        String id = "9876543";

        void info4(){
            info2();
            System.out.println("静态内部类方法");
            System.out.println("静态内部类属性" + name + " " + id);
            System.out.println("外部类静态属性:" + money);
        }
    }


}

public class Test {
    public static void main(String[] args) {
        System.out.println("======实例内部类初始化======");
        Person.Student p = new Person("小明", 20, "翻斗花园").new Student();
        p.info3();
        System.out.println("======静态内部类初始化======");
        Person.teacher q = new Person.teacher();
        q.info4();
    }
}

运行结果如下:

在这里插入图片描述

注意事项
  • 当内部类和外部类有重名属性时,优先读取内部类属性

  • 实例内部类成员方法可以读取调用外部类的任意成员

  • 静态内部类成员方法只能访问外部类的静态成员

  • 实例内部类可受修饰符的约束

局部内部类

定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,使用的非常少。

匿名内部类

匿名内部类没有名称,无构造函数。匿名内部类是一次性类,定义时同时创建它的对象,具体后续博客补充。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值