day06
程序员文章站
2022-03-14 10:16:30
...
Java类及类的成员
**面向过程(POP)**与 面向对象(OOP)
二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为,以函数为最小单位,虑怎么做。面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
属性:对应类中的成员变量,Field = 属性 = 成员变量(到web学习的时候,属性和字段名会有一点区别,不过,只要你遵守良好的书写习惯,自然就不会发生错误)
行为:对应类中的成员方法,Method = (成员)方法 = 函数
举一个例子:人,我们尝试去构造人这个类
人有姓名,年龄等等,我们先去构造一个名为Person的类
步骤:
-
定义类(考虑修饰符、类名)
-
编写类的属性(考虑修饰符、属性类型、属性名、初始化值)
-
编写类的方法(考虑修饰符、返回值类型、方法名、形参等)
package cap8;
public class OOPTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "张三";
p1.age = 20;
Person p2 = new Person();
p2.name = "李四";
p2.age = 10;
System.out.println(p1+",name="+p1.name+",age="+p1.age);
System.out.println(p2+",name="+p2.name+",age="+p2.age);
}
}
class Person{
String name;//姓名,这是一个属性
int age;//年龄,这也是一个属性
public void eat(){//这是一个行为,我们称为方法
System.out.println("思考中....");
}
public void run(){//这也是一个方法
System.out.println("跑...");
}
public void speak(String language){//这也是一个方法
System.out.println("说"+language);
}
}
/*
aaa@qq.com,name=张三,age=20
aaa@qq.com,name=李四,age=10
首先,我们要确定的是,这里的p1和p2不是同一个,因为打印的地址是不一样的,所以操作的空间也是不一样的
调用属性:对象.属性名
调用方法:对象.方法名()
*/
刚开始的时候,我们要记住
创建对象:类名 对象名= new 类名();
调用属性:对象.属性名
调用方法:对象.方法名()
这个到后期会有所变化和相应的限制
内存解析
类的访问机制
在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。(例外:static方法访问非static,编译不通过。)
例如:
class Person{
String name;
int age;
public void print(){
System.out.println(age+"==="+name);
}
}
在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中定义的成员。
例如:
Scanner sc = new Scanner(System.in);
String s = sc.next();
属性:
类中属性的使用
属性(成员变量) vs 局部变量
1.相同点:
1.1 定义变量的格式:数据类型 变量名 = 变量值
1.2 先声明,后使用
1.3 变量都有其对应的作用域
2.不同点:
2.1 在类中声明的位置的不同
属性:直接定义在类的一对{}内,==类中方法外==
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.2 关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected --->封装性
目前,大家声明属性时,都使用缺省就可以了。
局部变量:==不可以使用权限修饰符。==
2.3 默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值。
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0 (或'\u0000')
布尔型(boolean):false
引用数据类型(类、数组、接口):null
局部变量:==没有默认初始化值。==
意味着,我们在调用局部变量之前,一定要==显式赋值。==
特别地:形参在调用时,我们赋值即可。
public void run(){
String s;
System.out.println(s);//报错,没有赋值,局部变量是没有默认值的。
}
public void speak(String language){
String lang = language;
System.out.println("说"+language);//可以,调用方法时,肯定要传参数
System.out.println("说"+lang);
}
2.4 在内存中加载的位置:
属性:==加载到堆空间中 (非static)==
局部变量:==加载到栈空间==
方法
方法:描述类应该具有的功能。
* 比如:Math类:sqrt()\random() \...
* Scanner类:nextXxx() ...
* Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...
*
* 1.举例:
* public void eat(){}
* public void sleep(int hour){}
* public String getName(){}
* public String getNation(String nation){}
*
* 2. 方法的声明:权限修饰符 返回值类型 方法名(形参列表){
* 方法体
* }
* 注意:static、final、abstract 来修饰的方法,后面再讲。
*
* 3. 说明:
* 3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
* Java规定的4种权限修饰符:private、public、缺省、protected -->封装性再细说
*
* 3.2 返回值类型: 有返回值 vs 没有返回值
* 3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用
* return关键字来返回指定类型的变量或常量:“return 数据”。
* 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要
* 使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
*
* 3.2.2 我们定义方法该不该有返回值?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
*
* 3.4 形参列表: 方法可以声明0个,1个,或多个形参。
* 3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...
*
* 3.4.2 我们定义方法时,该不该定义形参?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.5 方法体:方法功能的体现。
*
* 4.return关键字的使用:
* 1.使用范围:使用在方法体中
* 2.作用:① 结束方法
* ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
* 3.注意点:return关键字后面不可以声明执行语句。
*
* 5. 方法的使用中,可以调用当前类的属性或方法
* 特殊的:方法A中又调用了方法A:递归方法。
* 方法中,不可以定义方法。
练习
定义类Student,包含三个属性:学号number(int),年级state(int),成绩
score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
package cap9;
/**
* 定义类Student,包含三个属性:学号number(int),年级state(int),成绩
* score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
* 问题一:打印出3年级(state值为3)的学生信息。
* 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
* @author xiao-liu
*
*/
public class TestObject {
public static void main(String[] args) {
Student[] studentArr = new Student[20];
for(int i = 0;i < 20;i++) {
Student student = new Student();
student.number = i+1;
student.state = (int)(Math.random()*(6-1+1)+1);//[1,6]年纪
student.score = (int)(Math.random()*(100-0+1)+0);//[0,100]成绩
studentArr[i] = student;
}
for(int i = 0;i < 20;i++) {
System.out.println(studentArr[i]+",编号:"
+studentArr[i].number+",年级:"
+studentArr[i].state+",分数:"
+studentArr[i].score);
}
System.out.println("=====");
//问题一:打印出3年级(state值为3)的学生信息。
for(int i = 0;i < 20;i++) {
if(studentArr[i].state == 3)
System.out.println(studentArr[i]+",编号:"
+studentArr[i].number+",年级:"
+studentArr[i].state+",分数:"
+studentArr[i].score);
}
//使用冒泡排序按学生成绩排序,并遍历所有学生信息
System.out.println("====");
for(int i = 0;i < studentArr.length-1;i++) {
for(int j = 0;j < studentArr.length-1-i;j++) {
if(studentArr[j].score>studentArr[j+1].score) {
Student s = studentArr[j];
studentArr[j] = studentArr[j+1];
studentArr[j+1] = s;
}
}
}
System.out.println("====");
for(int i = 0;i < 20;i++) {
System.out.println(studentArr[i]+",编号:"
+studentArr[i].number+",年级:"
+studentArr[i].state+",分数:"
+studentArr[i].score);
}
}
}
class Student{
int number;
int state;
int score;
}