java编程----类与对象

定义

  • OOP,面向对象编程
    • 类,成员属性、成员方法、构造器;
    • 三大特征:封装、继承、多态;
    • 关键字,this,super,static,final, abstract, interface, import, package
  • OOD,面向对象设计
  • 面向过程,强调功能实现的顺序,以函数为最小单位,如C语言;
  • 面向对象,强调功能实现的主题,以类/对象为最小单位,如java/python;

抽象数据类型,将不同的数据类型封装在一起,来描述一个新的事物。
,对一类事物共同特征的抽象,是一种抽象的数据类型;面向对象编程中需要先定义(抽象)出类;
对象,一类事物中具体的一个实例;

类、接口、数组、字符串是引用数据类型,使用new创建,如String就是引用类型,引用类型的默认值为null。

定义一个类

  • 类定义在一个.java类文件中;
  • 一个.java文件中只能有一个public类,且public类名与文件名相同;
  • 包含主函数的主类调用其他类,同一个包中的类可以直接使用,不同包中的类需要import导入;
  1. 创建项目,这里使用idea开发工具
    在这里插入图片描述
    在这里插入图片描述
    创建好的项目目录:
    在这里插入图片描述
    在src目录上,右键>new>package 创建一个包,名字自定义;
    在创建的包上,右键>new>java class 创建源文件xxx.java;
     
  2. 在.java文件中编写代码
// 创建一个学生类   Stu.java
public class Stu {
	// 成员属性
	String name = 'jack';
	int age;
	char sex;
	
	// 成员方法
	public void run(){
		System.out.println(name + "跑步中...");  // 只能输出一个字符串,必须拼接
	}
}
  1. 在主类的主方法中调用 学生类
import School.Stu;  //导入(其他包)的类文件,然后就可以切入到其内部的public类


//主类
public class Main {
    //主函数
    public static void main(String[] args) {
        // 创建学生对象
        Stu stu = new Stu();    
        // 成员属性都有默认值,int 0  float 0.0  boolean false char 0  引用类型null
        // 方法形参、方法内部变量为局部变量,没有默认初始化,必须先赋值,才可以使用
        // 成员变量(非static)随对象一起存入堆内存;而局部变量存入栈;
        //调用 成员方法
        stu.run(); 
    }
}

在主类代码中,右键run 即可

  1. 主类中的代码分析
    public,公共访问权限,主方法是一切程序的开始点,必须是公共的
    static,静态方法,类与实例对象均可以调用。
    void,无返回值
    main,固定的主方法,程序入口
    String[] args,字符串数组,程序启动时,接收参数;

  2. 当前目录结构
    在这里插入图片描述
    Main是主类的源文件;
    同一个包(文件夹)中的类之间可以相互引用,不用import导入;
    不同的包之间,就需要导入且只能引用public类(全局类);
    非public类(保留类)只能本包内部使用;
     

内存解析

  • 对象、数组使用new创建,存入堆内存中;
  • 虚拟机栈,存储局部变量;
  • 方法区,存储已被虚拟机加载的类、常量、static静态变量;
    在这里插入图片描述
  • 案例解析:
    • new一个对象存入堆;
    • main中声明变量赋值,即局部变量引用对象;
      在这里插入图片描述

构造方法

构造函数,用于创建对象时,初始化对象的属性值。
类似于python的__init__方法

  1. 必须与类名相同;
  2. 无返回值
  3. 创建对象时,自动调用构造函数
  4. 不写构造函数时,编译器提供一个无参构造函数;
  5. 写构造函数,编译器不再提供;可以重载;
public class Stu{
	int name;
	int age;
	public Stu(){
		//构造函数
		this.name = "jack";
		this.age = 23; // this代表当前对象
	}
	//重载构造函数
	public Stu(String name, int age){
		this.name = name;
		this.age = age;
	}
}

普通方法

类中就两种方法

  • 构造方法
  • 普通方法
    • 权限修饰符 返回类型 函数名(形参){ 函数体 };
    • 权限修饰符
      • public,公有,最大访问权限;
      • protected, 保护,访问受限;
      • private,私有,只能在类内部访问;
      • 缺省,
    • 返回值
      • void,无返回值,可以使用return结束;或者不写return;
      • int/float/double/String… 有返回值;函数体需要return对应类型;
    • 方法名,小驼峰+可读性
    • 形参,类型 + 形参名;定义时形参可有可无;
    • 方法体内部可以直接调用当前类的成员属性、成员方法(对象有则优先调用对象的);方法中不能再定义方法;
    • 静态方法内部只能调用静态的成员属性、成员方法
import java.util.Scanner;


public class Main{
    public static void main(String[] args){

        User.run();

        User user = new User("jack", 55);
        System.out.println(user.getAge());
    }
}


// 非public类
class User {
    static String name, password = "123";
    int age = 25;


    // 构造方法,初始化对象
    public User(String name, int age){ // 不指定返回类型
        // 初始化
        this.name = name;  // 属性必须在成员属性中定义出来
        this.age = age;
        System.out.println("构造函数被调用");
    }

    public static String getName(){
        return name;
    }

    public void walk(){
        System.out.println("i am walking." + password); // 对象没有 则调用类的password
    }
    public int getAge(){
        walk(); // 调用成员方法
        return age; // 调用成员属性(对象有则调用对象的,否则调用类的)
    }
    public static void run(){
        // 方法内部 可以调用类的属性、方法

        // 静态方法内部 只能调用类的静态属性
        System.out.println(name);

        // 静态方法内部,只能调用类的静态方法;
       getName();
    }
}

 

可变个数形参

  • jdk5.0新特性;
  • 参数格式:类型…变量名,收集参数放入数组,必须在所有参数的最后位置;
  • 自动匹配不确定个数的实参,将同类型的多个参数收集到数组中;
  • 函数名相同,与同类型的数组参数不能构成重载;
package School;

public class CollectArgs {
    public static void main(String[] args) {
        CollectArgs ca = new CollectArgs();
        ca.collectName("jack");
        ca.collectName(34, "tom", "lucy", "lili"); //  收集参数
    }

    // 单个参数
    public void collectName(String name){
        System.out.println(name + "\n");
    }

    // 收集多个参数,存入数组
    public void collectName(int numId, String...nameArr){
        System.out.println(numId);
        for (String s : nameArr) { // 强化的for
            System.out.print(s + " ");
        }
    }

	// 不与同类型的数组 构成重载
	public void collectName(int numId, String[] arr){}
}

 

方法参数的传递

  • 基本数据类型去赋值给一个变量,存入数值;对象、接口、数组、字符串等引用类型赋值,存入地址(引用);

  • 方法参数,(基本数据类型)值传递

  • 方法参数,(引用类型)地址传递

  • 案例1

package School;

public class Case1 {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        method(a, b); // 静态方法

        // 调用method后,输出a=100, b=200
        System.out.println("a=" + a);
        System.out.println("b=" + b);
    }

    public static void method(int a, int b){
        a *= 10;
        b *= 10;
        System.out.println("a=" + a);
        System.out.println("b=" + b);
        System.exit(0); // 进程退出  防止在外部打印
    }
}

 

方法的重载

  • 方法的签名,函数名+参数类型列表;一个类中不允许签名一样;
  • 方法的重载overload,同一个类中同函数名,但参数类型列表(包括顺序)不同;
    • 类型不同
    • 顺序不同;
    • 个数不同;
    • 与权限修饰符、返回值、参数名称、函数体无关;
  • 根据参数类型,选择调用不同的函数体;
public class Cell{
	int row;
	int col;
	void moveDown(){ // 同一个类,同名函数,不同参数类型/参数长度;
		row++;
	}
	// 方法的重载(参数不同)
	void moveDown(int n){
		row += n;
	}
}

this关键字

对象调用函数时,函数内部的this代表当前对象;内部使用的属性都是(this.)attr,前面有个this. ,表示当前对象的属性。
this() 调用构造函数,只能在构造函数内部使用。

public class Stu{
	int name;
	int age;
	public Stu(){
		//构造函数
		this("jack", 23); //调用构造函数
	}
	//重载构造函数
	public Stu(String name, int age){
		this.name = name;
		this.age = age;
	}
	void setName(String name){
		// this.表示当前对象  可以省略
		this.name = name;
	}
}

核心关键字

public,公有属性/方法,作用域范围内谁可以访问;
private,私有属性/方法,只在类内部使用,对象只能通过方法来操作私有属性;
protected,保护的属性/方法,只有本包中的类才能调用;
 
static,静态的属性是全局公共属性,保存在全局数据区;
静态的方法,不能使用this关键字;
静态的属性/方法,类与对象均可以调用。
同main方法并列的方法用static
 
final 定义类,不可以被继承
final 定义方法,不可以被覆盖(重写)
final 定义变量,为常量

 

内存管理

JVM的内存管理:

  • 堆 存储new创建的对象
  • 栈 存储临时变量
  • 方法区
    在这里插入图片描述
    在这里插入图片描述
    基本数据类型,分配内存并赋值,互不影响。
    c = null 无引用 空指针异常
     

案例

  • 面向对象 思路总结
    • 确定需要用到哪些对象
    • 抽象出类(属性、方法)
    • 定义类
    • 实例化对象
  • 定义一个Stu类,内部实现main方法、addAge方法、构造方法;
    • 构造方法,初始化对象的姓名、年龄;
    • addAge方法,实现年龄+n, n为参数;
    • main方法内部调用addAge方法;
    • 静态方法内部,只能访问静态的成员属性、静态的成员方法;非静态的使用实例调用
// 创建Stu.java类文件


// 类文件中只能有一个public 类,且类名与文件名相同
public class Stu { // 全局类   可以导入到任何类文件中
    // 成员属性(必须先定义,对象才可以使用)
    static String name = "Stu class"; // 静态的成员变量在方法区,只有一份
    int age;

    // 构造方法,初始化对象
    public Stu(String name, int age){
        // this为当前对象
        this.name = name;
        this.age = age;
    }
    public void addAge(int n) {
        age += n; // 对象调用,则表示实例对象的age属性 (谁调用 就是谁的属性)
    }

    // static方法
    public static void getName(){
        System.out.println(name);
    }
    // main
    public static void main(String[] args){
        // static静态方法内部,只能访问 静态的成员属性、静态的成员方法
        Stu stu = new Stu("jack", 23); // 非静态,则使用对象调用
        stu.addAge(5);
        System.out.println("学生年龄:" + stu.age);

        // 直接调用静态方法
        getName();

        Stu stu2 = new Stu("tom", 18);
        getName();
    }
}
  • 定义一个Stu类,成员属性为stuId, grade, score, 均为int类型;
    • 创建一个StuTest类,main方法中创建一个长度为10的Stu数组;
    • stuId 为1-10之间;
    • grade 为1-5,采用Math.random() 0-1之间的随机数;
    • score 为0-100,采用Math.random()随机,Math.round()四舍五入;
    • getStuInfo(Stu[] arr, int grade) 获取指定年级的学生信息;
    • bubbleSort(Stu[ ] arr) 按照分数冒泡升序排序
// School 包
// 创建Stu.java
package School;

public class Stu {
    // 成员变量
    int stuId, grade, score;

    // 构造方法初始化
    public Stu(int stuId, int grade, int score){
        this.stuId = stuId;
        this.grade = grade;
        this.score = score;
    }
}



// 创建StuTest.java
package School; // 声明 所在包


public class StuTest{
    public static void main(String[] args) {
        // 学生数组
        Stu[] arr = new Stu[10];
        for(int i=0; i<arr.length; i++){
            int stuId = i + 1;
            // Math.random() 0-1之间的随机数
            // Math.round() 四舍五入  返回long, 需要强制类型转换
            int grade = (int) Math.round(Math.random() * (5 - 1 + 1)) + 1;
            int score = (int) Math.round(Math.random() * (100 - 0 + 1));
            arr[i] = new Stu(stuId, grade, score);
        }

        // 获取4年级的学生信息
        getStuInfo(arr, 4);

        // 按照学生成绩升序排序
        bubbleSort(arr);
    }

    public static void getStuInfo(Stu[] arr, int grade){
        for(int i = 0; i < arr.length; i++){
            if(arr[i].grade == grade){
                printStuInfo(arr[i]);
            }
        }
    }

    public static void printStuInfo(Stu stu){
        System.out.println("学号:" + stu.stuId + "\n" + "年级:" +
                stu.grade + "\n" + "分数:" + stu.score + "\n");
    }
	// 非静态时,使用对象调用
    public static void bubbleSort(Stu[] arr){
        for(int i=0; i<arr.length-1; i++){
            for(int j=0; j<arr.length-1-i; j++){
                if(arr[j].score > arr[j+1].score){
                    Stu temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }

        // 数组为引用类型;
        for(int k=0; k<arr.length; k++){
            System.out.println(arr[k].score);
        }
    }
}

 

  • 控制俄罗斯方块水平位置、垂直位置
package School;

public class BlockGame {
    //本包 以外调用,必须是public
    public Cell cell = new Cell();
    //静态方法
    public static String testPosition(Cell cell){
        return cell.getPosition();
    }
    public void moveDown(Cell cell){
        cell.moveDown();
    }
}


class Cell{ //非public的保留类,只能包内部使用
    //行数 0 1 .. 39
    int row;   // 初始化时为0
    int col;
    // 向下移动
    public void moveDown(){
        if(row < 39){
            row++;
        }
    }
    //向左移动
    void moveLeft(){
        if(col > 0){
            col--;
        }
    }
    void moveRight(){
        if(col < 19){
            col++;
        }
    }
    String getPosition(){
        return row + ", " + col;
    }
}

在这里插入图片描述
必须是public的属性、方法才可以跨包使用。
非public的保留类,只能在本包内部使用,即使跨包拿到了保留类的对象,也无法跨包操作对象的属性、方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

laufing

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

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

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

打赏作者

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

抵扣说明:

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

余额充值