java类和对象

目录

一、类的定义

二、this引用

三、构造方法及对象的初始化

1、构造方法

2、对象的初始化

四、封装

五、包

1、包的概念

2、导入包中的类

3、自定义包

4、常见的包

六、static成员

1、static修饰成员变量

2、静态成员方法

七、代码块

八、对象的打印

九、内部类

1、实例内部类

2、静态内部类

3、局部内部类


 

一、类的定义

1、在java中定义类需要用到class关键字

class ClassName{
   filed; //成员变量(属性)
   method; //成员方法
}

【注意】

  • 类名采用大驼峰定义
  • 一般一个文件只能定义一个类
  • main方法所在的类一般要使用public修饰
  • public修饰的类必须与文件名相同
  • 不能随便修改public修饰的类的名称

2、类的使用(实例化)

定义类,就相当于在计算机中定义了一种新的类型用定义的类类型创建对象的过程,称为类的实例化。

//定义了一个狗类
class PetDog {
    public String name;//名字
    public String color;//颜色
    public void barks() {
        System.out.println(name + ": 旺旺旺~~~");
    } 
    public void wag() {
        System.out.println(name + ": 摇尾巴~~~");
    }
}
public class Main{
    public static void main(String[] args) {
        PetDog dogh = new PetDog(); //通过new实例化对象
        dogh.name = "阿黄";
        dogh.color = "黑黄";
        dogh.barks();
        dogh.wag();
}

【注意】

  • new关键字用于创建对象的实例
  • 使用【类名.成员/方法】来访问对象
  • 同一个类可以创建多个实例

二、this引用

java编译器给每个“成员方法”增加了一个隐藏的引用类型参数(this),该引用参数指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。(this引用的是调用成员方法的对象)

this的三种用法:

  • this.成员变量(成员变量不能是静态的)
  • this.成员方法(成员方法不能是静态的)
  • this()调用其他的构造方法(必须放在第一行)

对于以下代码:

public class Date {
    public int year;
    public int month;
    public int day;

    public void setDay(int y, int m, int d) {
        year = y;
        month = m;
        day = d;
    }
    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }
    public static void main(String[] args) {
// 构造三个日期类型的对象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
// 对d1,d2,d3的日期设置
        d1.setDay(2020, 9, 15);
        d2.setDay(2020, 9, 16);
        d3.setDay(2020, 9, 17);
// 打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

(1)形参名与成员变量名相同

根据局部变量优先原则,方法中的year都为方法的参数year,次数编译无法通过,需要通过this来调用类中的成员变量。

public void setDay(int year, int month, int day){
   this.year = year;
   this.month = month;
   this.day = day;
}

(2)当三个对象都在调用方法setDate和printDate时,函数不能确定打印的是那个对象的数据,此时需要this来确定打印对象。

public void printDate(){
    System.out.println(this.year + "/" + this.month + "/" + this.day);
}

【注】

  • this只能在“成员方法”中使用
  • this的类型:对应类的引用类型
  • 在“成员方法”中,this只能引用当前对象,不能引用其它对象,具有final(相当于C++中的const)属性
  • this不能为空

三、构造方法及对象的初始化

1、构造方法

是一种特殊的成员方法。名字必须与类名相同,创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

【特性】

  • 名字必须与类名相同。
  • 没有返回值类型,设置为void也不行。
  • 构造方法至少一个,可以是多个。
  • 创建对象时编译器自动调用,并且在对象的生命周期中只调用一次。
  • 构造方法可以重载。(可以根据自己的需求提供不同参数的构造方法)
public class Date {
    public int year;
    public int month;
    public int day;
    // 无参构造方法
    public Date() {
        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调用另一个构造方法。
public class Date {
    public int year;
    public int month;
    public int day;
    //不带参数的构造方法
    public Date(){
        this(1900, 1, 1);
        System.out.println(year);
    } 
    // 带有三个参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

【注】

  1. this必须是构造方法中的第一条语句。
  2. 不能形成环
  • 绝大多数情况下使用public修饰,特殊情境下会被private修饰

2、对象的初始化

(1)默认初始化

局部变量在使用时必须要初始化,而成员变量不用。因为new会调用构造方法,给对象中各个成员赋值。

new关键字在虚拟机中的工作:

  • 检查对象对应的类是否加载
  • 为对象分配内存空间
  • 处理并发问题(多个线程同时申请空间,JVM要保证给对象分配的空间不冲突)
  • 初始化所分配的空间
  • 设置对象头信息
  • 调用构造方法,给对象中各个成员赋值

(2)就地初始化

在声明成员变量时,直接给出初始值。

四、封装

面向对象程序的三大特性:封装、继承、多态。

封装:从语法层次来说,就是将字段或方法用private进行修饰,使其只能在当前类使用,起到了封装的作用

【访问限定符】

Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段能否直接在类外使用。java中提供了四种访问权限符:

范围privatedefaultprotectedpublic
同一个包的同一个类

同一个包的不同类 
不同包中的子类  
不同包中的非子类   

对于private修饰的变量,我们可以通过get和set方法来获取和操作它。

(右键→Generate→GetterandSetter)即可

public class Computer {
    private String cpu;// cpu
    public String getCpu() {
        return cpu;
    }
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
}

【说明】

  • protected主要用在继承中
  • default权限:什么都不写时的默认权限
  • 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
     

【注】一般情况下,成员变量设置为private,成员方法设置为public

五、包

1、包的概念

软件包:为了更厚的管理类,把多个类收集在一起成为一组,称为包。

在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。

2、导入包中的类

使用import语句导入包。

import java.util.Date;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
    }
}

如果需要使用  java.util  中的其它类,可以使用  import java.uti.*

对于以下情况:

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        System.out.println(date.getTime());
    }
}

两个包中都存在Date类,此时我们需要引用完整的类名,否则编译器不知道调用哪个包下的Date类。

3、自定义包

【基本规则】

  • 在文件的最上方加上一个package语句,指定该代码所在的包
  • 包名尽量指定为唯一的名字,通常用公司域名的颠倒形式
  • 报名要和代码路径相匹配
  • 如果一个类没有package语句,则该类被放在一个默认包中

【新建包】右键src→新建→包

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUHJldGVuZC4u,size_20,color_FFFFFF,t_70,g_se,x_16

【新建类】右键包名→新建→类 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUHJldGVuZC4u,size_20,color_FFFFFF,t_70,g_se,x_16

4、常见的包

  • Java.lang:系统常见基础类(String 、Object)编译器会自动导入
  • java.lang.reflect:java反射程序包
  • java.net:进行网络编程开发包
  • java.sql:进行数据库开发的支持包
  • java.util:java提供的工具程序包
  • java.io:I/O编程开发包

六、static成员

在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,不属于某个具体的对象,是所有的对象共享的。

静态的成员变量和成员方法都是不依赖于对象的

1、static修饰成员变量

【静态成员变量特性】

  • 不属于某个具体的对象,是类的属性,所有对象所共享的,不存储在某个对象的空间中
  • 可以通过对象访问,也可以通过类访问,推荐使用类访问
  • 类变量存储在方法区中
  • 生命周期伴随类的一生(随类的加载创建,类的卸载销毁)

2、静态成员方法

【静态成员方法特性】

  • 不属于某个具体的对象,是类方法
  • 通过  类名.静态方法名(……)方式调用
  • 不能在静态方法中访问任何非静态成员变量(静态方法没有隐藏的this引用参数)
public static String getClassRoom(){
        System.out.println(this);
        return classRoom;
} 
// 编译失败:Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this
public static String getClassRoom(){
        age += 1;
        return classRoom;
} 
// 编译失败:Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 ag
  • 静态方法中不能调用任何非静态方法,(非静态方法有this参数,在静态方法中调用时无法传递)

七、代码块

【注】代码块的执行顺序:

父类静态代码块(只执行一次)➡️子类静态代码块→父类实例代码块→父类构造方法➡️子类实例代码块➡️子类构造代码快

public class Student{
        private String name;   //实例成员变量
        private String gender;
        private int age;
        private double score;
        private static String classRoom;
        //实例代码块
        {
            this.name = "bit";
            this.age = 12;
            this.gender = "man";
            System.out.println("I am instance init()!");
        }
        // 静态代码块
        static {
            classRoom = "bit306";
            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、构造代码块:定义在类中的代码块。也称实例代码块,一般用于初始化实例成员变量

定义在类的内部,和构造方法同级。

3、静态代码块:使用static修饰的代码块。一般用于初始化静态成员变量

【注】

  • 无论生成多少个对象,静态代码块只执行一次
  • 静态成员变量是类的属性,在JVM加载类是开辟空间并初始化
  • 如果一个类包含多个静态代码块,在编译代码时,编译器会按照定义的先后顺序合并,最终放在生成的<>方法中,该方法在加载类时调用,并且只调用一次。
  • 实例代码块只有在创建对象时才会执行

八、对象的打印

当类中有多个成员变量,我们需要打印对象中内容,此时应该重写toString方法。

(鼠标右击→Generate→toString())即可

 public class Person {
        String name;
        String gender;
        int age;
        public Person(String name, String gender, int age) {
            this.name = name;
            this.gender = gender;
            this.age = age;
        } 
        @ Override
        public String toString() {
            return "[" + name + "," + gender + "," + age + "]";
        } 
        public static void main(String[] args) {
            Person person = new Person("Jim","男", 18);
            System.out.println(person);
        }
    } // 输出结果:[Jim,男,18] 

当我们调用System.out.println();时,

编译器会默认调用Object的toString方法,如果当前类对toString方法重写,则会调用自己的toString方法。(重写需要用到@Override,起到检查的作用)

九、内部类

在java中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

1、实例内部类

定义在类中,未被static修饰的类

【注】

  • 创建内部类对象

OutClass.InnerClass  innerClass=new OutClass().new InnerClass();

外部类.内部类  变量=外部类对象的引用.new 内部类()

  • 实例内部类中,创建的成员变量不能是static的,如果定义只能是static final
  • 如果内部类和外部类具有相同名称的成员,优先访问的是内部类的
  • 如果需要访问外部类的同名成员变量,必须  (外部类名称.this.同名成员)

2、静态内部类

被static修饰的内部成员类

【注】

  • 创建静态内部类对象

OutClass.InnerClass innerclass=new OutClass.InnerClass();

  • 在创建静态内部类对象时,不需要先创建外部类对象
  • 成员内部类,经过编译之后会生成独立的字节码文件,命名格式为:外部类名称.内部类名称
  • 在静态内部类中只能访问外部类的静态成员

3、局部内部类

定义在外部类的方法中,这种内部类只能在其定义的位置使用,一般使用的非常少

【注】

  • 局部内部类只能在定义的方法体内使用
  • 不能被public、static等修饰符修饰
  • 几乎不会使用

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喜欢敲代码的大秃噜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值