JAVA学习笔记5,面向对象this,import,package,构造器,权限修饰符使用范围

这篇博客详细介绍了JAVA面向对象编程的基础知识,包括面向对象的三大特征(封装性、继承性、多态性)、类和对象的概念、类的语法格式、对象的创建和使用、类的访问机制、匿名对象、权限修饰符、成员变量与局部变量的区别、方法的重载、构造器的使用、this关键字、package关键字以及import关键字的含义和使用。博客内容深入浅出,适合初学者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 面向对象的三大特征

  1. 封装性
  2. 继承性
  3. 多态性

二 类和对象的概念

  1. 类是对一类事物的描述,是抽象的、概念上的定义
  2. 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
  3. 类好比是汽车的图纸,对象就是根据图纸制造出来的汽车。
  4. 面向对象的重点就是类的设计。类的设计的重点就是类成员属性和方法的设计。
  5. 类的成员有成员变量、成员方法、构造器、代码块、内部类
public class Person {
    int age;//成员变量
    String name;//成员变量
    public Person() {//构造方法
    }
    public void printName(){//成员方法
    }
    {//代码块
        age=10;
    }
    class heart{//内部类
    }    
}

三 类的语法格式

修饰符 class 类名 {
    属性声明;
    方法声明; }
    说明:修饰符public:类可以被任意访问
    类的正文要用{ }括起来
举例:
public class Person{
    private int age ; //声明私有变量 age
    public void showAge(int i) { //声明方法showAge( )
        age = i; 
    } 
}

对于class的权限修饰只可以用public和default(缺省)。

  • public类可以在任意地方被访问。
  • default类只可以被同一个包内部的类访问。

四 对象的创建和使用

  • 创建对象语法: 类名 对象名 = new 类名();
  • 使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)
  • 如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。这表明如果我们修改一个对象的属性a(非static),则不影响另外一个对象属性a的值。

五 类的访问机制

  1. 在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(static方法访问非static,编译不通过。)
public class ClassTest {
    public static void main(String[] args) {
        new TT().names();
    }
}

class TT{
    static String name="111";
    int num=33;
    public void names() {
        System.out.println(name);非静态方法可以访问静态变量
    }

    public static void namess() {
        //System.out.println(num);//静态方法访问非静态变量报错
    }
}
  1. 在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中定义的成员。
  2. 内存解析
    • 堆(Heap):此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
    • 栈(Stack):是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char 、short 、 int 、 float 、 long 、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
    • 方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
Person p = new Person();
P.age=1;
p.name="wang";

内存解析图

六 匿名对象的使用

  1. 可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。如:new Person().getMoney();
  2. 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
  3. 经常将匿名对象作为实参传递给一个方法调用。

七 权限修饰符

常用的权限修饰符有:private、缺省、protected、public

八 成员变量与局部变量

  • 在方法体外,类体内声明的变量称为成员变量。
  • 在方法体内部声明的变量称为局部变量。

8.1 成员变量

  • 语法格式:修饰符 数据类型 属性名 = 初始化值 ;
    • 初始化值:可以是任何基本数据类型(如int、Boolean) 或 任何引用数据类型。
    • 常用的权限修饰符有:private、缺省、potected、public。
    • 其他修饰符:static、final
class User{
    //属性(或成员变量)
    String name;
    public int age;
    boolean isMale;
    public void talk(String language){//language:形参,也是局部变量
        System.out.println("我们使用" + language + "进行交流");        
    }    
    public void eat(){
        String food = "面条";//局部变量
        System.out.println("我喜欢吃:" + food);
    }
}

8.2 局部变量

  • 形参(在方法、构造器中定义的变量)
  • 方法局部变量 (在方法体中定义的变量)
  • 代码块局部变量(在代码块定义的变量)
  • 局部变量不能用权限修饰符,没有默认初始化值。
  • 局部变量除形参外,均需显式初始化,没有默认初始化值。

九 类的方法

  • 方法是类或对象行为特征的抽象,用来完成某个功能操作,
    也称为函数。
  • 将功能封装为方法的目的是,可以实现代码重用,简化代码
  • Java里的方法不能独立存在,所有的方法必须定义在类里。
  • 方法申明:
    修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
        方法体程序代码
        return 返回值;
     }
  • 返回值类型
    • 没有返回值:void。
    • 有返回值,声明出返回值的类型。与方法体中“return 返回值”搭配使用。
    • 方法名:属于标识符,命名时遵循标识符命名规则和规范。
    • 形参列表:可以包含零个,一个或多个参数。多个参数时,中间用“,”隔开
    • 返回值:方法在执行完毕后返还给调用它的程序的数据。
  • 注 意
    • 方法被调用一次,就会执行一次
    • 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
    • 定义方法时,方法的结果应该返回给调用者,交由调用者处理。
    • 方法中只能调用方法或属性,不可以在方法内部定义方法。

9.1 练习

定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。

  • 问题一:打印出3年级(state值为3)的学生信息。
  • 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
class Student {
    public int id;//学号
    public int state;//年级
    public int score;//分数

    public Student(int id,int state,int score){
        this.id=id;
        this.state=state;
        this.score=score;
    }
    public Student(){}
}
import java.util.Random;
import org.junit.Test;
public class App {
    /**
     * 生成20个Student对象的数组
     * @return Student[] 20个Student对象
     */
    public Student[] students() {
        Student stu[]=new Student[20];
        Random r = new Random();
        for (int i = 0; i < stu.length; i++) {
            stu[i]=new Student();
            stu[i].id=i+1;
            stu[i].state=r.nextInt(3)+1;
            stu[i].score=r.nextInt(100)+1;
        }
        return stu;
    }

    @Test
    public void getInfoOf3() {
        // 打印出3年级(state值为3)的学生信息
        Student stu[]=students();
        for (int i = 0; i < stu.length; i++) {
            if (stu[i].state == 3) {
                System.out.println("学号:"+stu[i].id+",年级:"+stu[i].state+",分数:"+stu[i].score);
            }
        }
    }

    @Test
    public void sort() {
        // 使用冒泡排序按学生成绩排序,并遍历所有学生信息
        Student stu[]=students();
        for (int i = 0; i < stu.length-1; i++) {
            for (int j = 0; j < stu.length-i-1; j++) {
                if (stu[j].score>stu[j+1].score) {
                    int temp=stu[j].score;
                    stu[j].score=stu[j+1].score;
                    stu[j+1].score=temp;
                }
            }
        }
        for (int i = 0; i < stu.length; i++) {
            System.out.println("学号:"+stu[i].id+",年级:"+stu[i].state+",分数:"+stu[i].score);
        }
    }
}

十 方法的重载(overload)

10.1 重载的概念

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

10.2 重载的特点

与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类 型)。调用时,根据方法参数列表的不同来区别。

10.3 重载示例:

//返回两个整数的和 
int add(int x,int y){return x+y;} 
//返回三个整数的和 
int add(int x,int y,int z){return x+y+z;} 
//返回两个小数的和 
double add(double x,double y){return x+y;}

10.4 可变个数的形参

  • 采用数组形参来定义方法,传入多个同一类型变量:
    public static void test(int a ,String[] books);
  • 采用可变个数形参来定义方法,传入多个同一类型变量:
    public static void test(int a ,String…books);
  • 声明格式:方法名(参数的类型名 …参数名)
  • 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
  • 可变个数形参的方法与同名的方法之间,彼此构成重载
  • 可变参数方法的使用与方法参数部分使用数组是一致的
  • 方法的参数部分有可变形参,需要放在形参声明的最后
  • 在一个方法的形参位置,最多只能声明一个可变个数形参
public void print() {
    change();//没有参数
    change("1");//1 
    change("1","2");//1 2
    change(new String[]{"1","2","3"});// 1 2 3
}
public void change(String...str){
    if (str.length==0) {
        System.out.println("没有参数");
    } else {
        for (int i = 0; i < str.length; i++) {
            System.out.print(str[i]+" ");
        }
        System.out.println();
    }
}

10.5 递归

  1. 递归方法:一个方法体内调用它自身。
  2. 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
  3. 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
  4. 练习
    1. 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0 的整数,求f(10)的值。
@Test
public void getSumTest() {
    /* 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0
的整数,求f(10)的值。 */
    System.out.println(getSum(10));//10497
}

public int getSum(int n) {
    if (n==0) {
        return 1;
    } else if(n==1){
        return 4;
    }else{
        return 2*getSum(n-1)+getSum(n-2);
    }
}

2. 已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n), 其中n是大于0的整数,求f(10)的值。

@Test
public void getSumTest() {
    /* 已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n), 其中n是大于0的整数,求f(10)的值。  */
    System.out.println(getSum(10));//-3371
}

public int getSum(int n) {
    if (n==20) {
        return 1;
    } else if(n==21){
        return 4;
    }else{
        return getSum(n+2)-2*getSum(n+1);
    }
}

3. 输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值。规律:一个数等于前两个数之和

@Test
public void getSumTest() {
    /* 输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值 规律:一个数等于前两个数之和  1 1 2 3 5... */
    System.out.println(getSum(10));//55
}

public int getSum(int n) {
    if (n==1) {
        return 1;
    } else if(n==2){
        return 1;
    }else{
        return getSum(n-2)+getSum(n-1);
    }
}

十一 封装性

程序设计追求“高内聚,低耦合”。

  • 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;
  • 低耦合 :仅对外暴露少量的方法用于使用。

隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性,这就是封装性的设计思想。

通过将数据声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:

  • 隐藏一个类中不需要对外提供的实现细节;
  • 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
  • 便于修改,增强代码的可维护性;

11.1 权限修饰符

修饰符同一个工程不同包子类同一个包类内部
publicyesyesyesyes
protectnoyesyesyes
defaultnonoyesyes
privatenononoyes

Ps:对于class的权限修饰只可以用public和default(缺省)。

十二 构造器

12.1 构造器的特征

  1. 具有与类相同的名称
  2. 不声明返回值类型。(不能写void)
  3. 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值

12.2 构造器的作用

在对象创建的时候进行初始化

12.3 语法格式

修饰符 类名 (参数列表) {
        初始化语句;
}

根据参数不同,构造器可以分为如下两类:

  • 隐式无参构造器(系统默认提供)
  • 显式定义一个或多个构造器(无参、有参)

注意:

  1. Java语言中,每个类都至少有一个构造器
  2. 默认构造器的修饰符与所属类的修饰符一致
  3. 一旦显式定义了构造器,则系统不再提供默认构造器
  4. 一个类可以创建多个重载的构造器
  5. 父类的构造器不可被子类继承

12.4 构造器重载

  • 构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。
  • 构造器重载,参数列表必须不同

12.5 成员属性的赋值顺序

  • 赋值的位置:
    • ① 默认初始化
    • ② 显式初始化
    • ③ 构造器中初始化
    • ④ 通过“对象.属性“或“对象.方法”的方式赋值
  • 赋值的先后顺序:
    • ① - ② - ③ - ④

十三 this关键字

1 在方法内部使用,即这个方法所属对象的引用;

2 在构造器内部使用,表示该构造器正在初始化的对象。

3 this 可以调用类的属性、方法和构造器

4 当在方法内需要用到调用该方法的对象时,用this来区分属性和局部变量,比如:this.name = name;


5 注意:

  1. 当形参与成员变量同名时,如果在方法内或构造器内需要使用成员变量,必须添加this来表明该变量是类的成员变量
  2. 使用this访问属性和方法时,如果在本类中未找到,会从父类中查找
  3. this可以作为一个类中构造器相互调用的特殊格式
  4. 构造器中不能通过"this(形参列表)"的方式调用自身构造器
  5. 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(形参列表)"
  6. "this(形参列表)"必须声明在类的构造器的首行
  7. 在类的一个构造器中,最多只能声明一个"this(形参列表)"

十四 package关键字

1 package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。它的格式为:package 顶层包名.子包名 ;

2 包对应于文件系统的目录,package语句中,用 “.” 来指明包(目录)的层次;

3 包通常用小写单词标识。

4 包的作用:

  • 包帮助管理大型软件系统:将功能相近的类划分到同一个包中。
  • 包可以包含类和子包,划分项目层次,便于管理
  • 解决类命名冲突的问题
  • 控制访问权限

十五 import 关键字

为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*)。import语句告诉编译器到哪里去寻找类。
语法格式:import 包名. 类名;
ps:

  1. 在源文件中使用import显式的导入指定包下的类或接口
  2. 声明在包的声明和类的声明之间。
  3. 如果需要导入多个类或接口,那么就并列显式多个import语句即可
  4. 举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
  5. 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
  6. 如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
  7. 如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
  8. import static组合的使用:调用指定类或接口下的静态的属性或方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值