java全端课2--java-面向对象(上)

方法

声明的格式:

arduino 复制代码
public class 类名{
    【修饰符】 返回值类型  方法名(【形参列表】){
        方法体语句;
    }
}

//【】表示可选

方法调用过程内存分析

  • 入栈:当方法被调用执行时,JVM会给这个方法在"栈"内存开辟一块独立的内存空间,用于存储这个方法的局部变量等信息。
  • 出栈:当这个方法调用结束,JVM会自动释放这个方法占用的栈内存空间。
  • (栈:先进后出)

方法的参数传递机制

  1. 参数是基本数据类型 结论:参数是基本数据类型时,实参把数据值copy给形参之后,它们就没关系了。形参无论怎么修改,都与实参无关。
  2. 参数是引用数据类型 Java的类,数组等都是引用数据类型,参数是引用数据类型(8种基本数据类型以外),实参给形参的是首地址的副本,意味着形参和实参指向同一个对象,所以形参的修改会影响实参。
  3. 凡是new操作的都在堆。
  4. 出栈释放的是栈内存空间,不会自动释放堆内存空间。

快捷键

  1. 生成main方法
  • main + 回车
  • psvm + 回车
  1. 变量大于
  • soutv: 默认输出离它最近的变量的值
  • 变量.soutv:输出对应变量的值

方法的重载

  1. 方法的重载:

在同一个类中,出现两个方法的名称相同,形参列表不同,这样的形式称为方法的重载。方法重载与修饰符、返回值类型、方法体无关。

形参列表不同:可以是个数不同,类型不同,顺序不同,不看形参名

  1. 为什么要重载?

方法名见名知意,如果两个方法的功能是相同的,那么它的名称就应该一样

  1. 重载方法的调用原则

先找实参的个数、类型、顺序与形参完全匹配的,如果找到了,就可以确定了 如果没找到完全匹配的,要找可以兼容的,大的类型可以兼容小的类型,例如double可以兼容int

调用重载的方法时,光标至于括号中,Ctrl+P 可查看所匹配的方法参数类型。

可变参数

可变参数是指参数的个数不确定,可以是0~n个参数值。

可变参数的标记符号:...

可变参数的使用方式,用使用数组的方式使用它即可。

可变参数 数组类型
形式(以int为例) int... int[]
调用时 可以传入0~n个元素,也可以直接传入数组 只能传入数组
限制 一个方法最多只能有1个可变参数,而且必须是最后一个形参 没有限制

面向对象的基本概念

1.1 什么是面向对象?

面向对象是一种编程的思想,编程的方式。

面向过程是另一种非常经典的编程思想。

面向过程是以步骤/过程为中心,面向对象是以类和对象为中心。

举例:把大象装进冰箱的代码实现

面向过程:

  • 第一步:把冰箱门打开
  • 第二步:把大象装进去
  • 第三步:把冰箱门关上

面向对象:

角色/对象:人、冰箱、大象

每一个角色需要完成什么事,能干什么事,或具有什么功能:

  • 人:推和拉的能力
  • 大象:走
  • 冰箱:打开,关上,冷冻...
java 复制代码
public class 人{
    public void 推(东西){
        //....
    }
    public void 拉(东西){
        //....
    }
}
java 复制代码
public class 大象{
    public void 走(){
        //...
    }
}
java 复制代码
public class 冰箱{
    public void 打开(){
        //...
    }
    public void 关上(){
        //...
    }
    public void 冷冻(){
        //...
    }
}
java 复制代码
public class 主类{
    public static void main(String[] args){
        人 ren = new 人("张三");
        大象 e = new 大象("亚洲", 10 );
        冰箱 b = new 冰箱("格力", 5,10,10);
        
        ren.拉(b);
        ren.拉(e);
        ren.推(e);
        ren.推(b);
    }
}

1.2 类与对象的概念

1、什么是类

生活中把事物也会进行分"类"。

Java中也要进行"分类",把一类具有相同特性/特征的事物用一个Java来描述。例如:

要做一个学生考试管理系统,学生:张三、李四、王五等,他们的共同特征:

  • 数据特征:姓名、年龄、性别、身份号码.... => 类的属性
  • 行为特征:注册、登录、考试、查看成绩... => 类的方法

总结:一类具有相同特性的事物的抽象描述。

2、什么是对象

对象是指这类事物的一个具体的个体,实体。

3、类与对象的关系

类是创建对象的模板,设计图。比喻:造汽车,先有汽车的设计图。设计图中体现了这里车的所有特征/构造/结构和功能。

对象是具体的实例,个体。比喻:对象是具体的一辆车,能开的车。

1.3 如何声明类和创建对象?

先有类还是先有对象?

从需求分析/设计项目的角度:先观察对象,才能总结有哪些类?

从代码实现的角度来说:先声明类,后创建对象。

1、声明类的格式

java 复制代码
【修饰符】 class 类名{
    
}

public的类有一个要求,类名与xx.java的源文件名必须一致。

类名:见名知意。遵循大驼峰命名法,即每一个单词首字母大写。

java 复制代码
public class Student {
}

2、创建对象的格式

java 复制代码
类名 对象名 = new 类名();

new是用来创建实例对象的关键字,实际意义是在堆中开辟一块内存用于存储对象的信息。例如:创建数组对象时,在堆中开辟一块空间,用来存储数组的元素。

java 复制代码
public class TestStudent {//主类,包含主方法的类
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();
        Student s3 = new Student();

        System.out.println(s1);//Student@4eec7777
        System.out.println(s2);//Student@3b07d329
        System.out.println(s3);//Student@41629346
        //s1,s2,s3都是引用数据类型的变量,s1,s2,s3中都是存储对象的首地址。
        //这一点与数组一样

        int[] arr = {1,2,3,4};
        System.out.println(arr);//[I@404b9385
    }
}

Student是一个类,也是一种数据类型,称为类类型。它与String是一样的。只不过String是JRE核心类库中已经提前写好的类,Student是咱们自己写的类。同理,数组类型,例如:int[],String[],double[]也是数据类型,是数组类型。它们统统都是引用数据类型。

1.4 包

1.4.1 包的作用

  • 可以通过不同的文件夹/包帮我们管理众多的类,分门别类进行管理,便于后期的维护
  • 可以避免类的重名,有了包之后,类的全名称就是包.类名
  • 包结合权限修饰符(public,protected,缺省,private等)来限定类或成员可见性范围。关于权限修饰符后面再讲。

1.4.2 如何声明包?

java 复制代码
package 包名;
  • 这句代码必须在源文件的首行。
  • 包名的命名规范:所有单词都小写,单词直接使用.分割。习惯上用公司域名倒置的写法,例如:com.123vwu.xxx

1.4.3 如何跨包使用类

  • 如果是同一个包,类之间互相使用,不需要import
  • 如果是跨包(不同包),类之间互相使用,必须import 或 使用类的全名称
  • 只有public修饰的类才能跨包使用
  • java.lang包的类,在任意地方使用都不需要导包,例如:String,Math,System 它们都是java.lang包的类
  • 如果需要导入不同包中的相同类名,只能一个是 import,一个是全名称,或者两个都全名称

1.5 类的成员之一:成员变量

1.5.1 成员变量的声明格式

java 复制代码
【修饰符】 class 类名{
    【修饰符】 数据类型 变量名;
}

成员变量的声明位置:类中方法外。

如果把变量定义/声明到方法里面,那就是局部变量,不是成员变量。

【修饰符】:暂时都是public

1.5.2 成员变量的分类

1、静态变量

静态变量不依赖于对象,不属于对象,属于类。跨类使用它,建议通过"类名.静态变量"。也可以通过"对象.静态变量"。

2、实例变量/非静态成员变量

实例变量依赖于对象,属于对象。跨类使用它,必须通过"对象.实例变量"。

对于静态变量的跨类访问,建议用类名.静态变量 如果用对象.静态变量,编译能通过,不会报错。 但是:1. 容易误导其他开发人员,错误理解成访问的是实例变量。2. 给编译器增加工作量,编译器最终还是需要翻译成类名.静态变量.

1.5.3 成员变量的特点

1、成员变量有默认值
类型 默认值
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
char '\u0000'
boolean false
String等类、数组等引用数据类型 null
2、是否共享性特点

静态变量的值是所有对象共享的,因为它属于类,而类是创建对象模板。

实例变量的值是每一个对象独立的,因为它属于某个对象。

问:成员变量该不该加static?

原则:看这个成员变量的值是不是所有对象共享的,只存一份的,如果是,就应该是静态的,否则就不能是静态的。

1.5.4 示例代码

java 复制代码
package com.test.field;

public class Teacher {
    //静态变量,静态成员变量,学校名是所有老师共享的
    public static String school;

    //实例变量,非静态成员变量,姓名、年龄、薪资是每一个老师独立的
    public String name;//姓名
    public int age;//年龄
    public double salary;//薪资
}
java 复制代码
package com.test.field;

public class TestTeacher {
    public static void main(String[] args) {
//        System.out.println("姓名:" + name);//错误,name在Teacher类中
       // System.out.println("姓名:" + Teacher.name);//错误,因为name没有static

        System.out.println("学校:" + Teacher.school);//null

        Teacher t1 = new Teacher();//创建对象,创建实例
        System.out.println("t1的姓名:" + t1.name);//null
        System.out.println("t1的年龄:" + t1.age);//0
        System.out.println("t1的薪资:" + t1.salary);//0.0

//        int a;//局部变量
//        System.out.println("a = " + a);//报错,因为a没有初始化

        System.out.println("赋值之前:");

        Teacher.school = "大学";
        t1.name = "张三";
        t1.age = 23;
        t1.salary = 16500;

        Teacher t2 = new Teacher();
        t2.school = "微客鸟窝";//推荐用 Teacher.school = "微客鸟窝";

        System.out.println("t1的学校:" + t1.school);//推荐用 Teacher.school
        System.out.println("t1的姓名:" + t1.name);
        System.out.println("t1的年龄:" + t1.age);
        System.out.println("t1的薪资:" + t1.salary);

        System.out.println("t2的学校:" + t2.school);//推荐用 Teacher.school
        System.out.println("t2的姓名:" + t2.name);
        System.out.println("t2的年龄:" + t2.age);
        System.out.println("t2的薪资:" + t2.salary);

    }
}
java 复制代码
package com.test.field;

public class Chinese {//中国人
    //国家名是所有中国人共享的,所以是静态的
    private static String country;
    
    //每一个中国人的名字是独立的,所以是非静态的
    private String name;
}
java 复制代码
package com.test.field;

public class Account {//银行账号
    //银行利率是大家统一的,所以是静态的
    private static double rate;//利率
    
    //余额是每个人不同的,所以是非静态的
    private double balance;//余额
}

1.5.5 引用数据类型的成员变量

java 复制代码
package com.test.field;

public class Husband {//丈夫
    //以下是两个引用数据类型的实例变量
    public String name;
    public Wife wife;
}
java 复制代码
package com.test.field;

public class Wife {//妻子
    //以下是两个引用数据类型的实例变量
    public String name;
    public Husband husband;
}
java 复制代码
package com.test.field;

public class TestHusbandWife {//主类,测试类
    public static void main(String[] args) {
        Husband h = new Husband();
        h.name = "张三";

        Wife w = new Wife();
        w.name = "翠花";

        h.wife = w;//给h.wife变量赋值一个Wife类型的对象
        w.husband = h;

        System.out.println("丈夫的姓名:" + h.name +",他妻子的姓名:" + h.wife.name);
        System.out.println("妻子的姓名:" + w.name +",她的丈夫的姓名:" + w.husband.name);
    }
}

1.6 类的成员之二:成员方法

1.6.1 成员方法的声明格式

java 复制代码
【修饰符】 class 类名{
  【修饰符】 返回值类型 方法名(【形参列表】){
    方法体语句;
  }
}

1.6.2 成员方法的分类

  1. 静态方法
  • 态方法中,只可以访问本类的静态成员,包括本类的静态方法和静态变量。
  • 跨类调用静态方法,建议使用"类名.静态方法",当然也可以通过"对象.静态方法"。
  1. 实例方法/非静态方法
  • 实例方法中,可以访问本类的所有成员,包括本类的静态成员和非静态成员。
  • 跨类调用非静态方法/实例方法,只可以通过"对象.非静态方法"的方式。

问:什么时候用静态方法,什么时候用非静态方法呢?

答:原则,如果在方法体中,需要访问本类的非静态成员,那么这个方法只能是非静态的。

相关推荐
小信啊啊17 分钟前
Go语言切片slice
开发语言·后端·golang
Victor3562 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易2 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧2 小时前
Range循环和切片
前端·后端·学习·golang
WizLC2 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor3562 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法2 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长3 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端
Python编程学习圈4 小时前
Asciinema - 终端日志记录神器,开发者的福音
后端
bing.shao4 小时前
Golang 高并发秒杀系统踩坑
开发语言·后端·golang