面向对象
JAVA类及类的成员:属性、方法、构造器;代码块、内部类
面向对象三大特征:封装性、继承性、多态性、(抽象性)
其他关键字:this、super、static、final、abstract、interface、package、import
面向过程与面向对象
二者都是一种思想,面向对象是相对于面向过程而言的。面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。面向对象,将功能封装进对象,强调了具备了功能的对象,以类/对象为最小单位,考虑谁来做。
面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如 抽象、分类、继承、聚合、多态等。
面向对象的三大特性:
封装 (Encapsulation)
继承 (Inheritance)
多态 (Polymorphism)
面向对象的思想概述
程序员从面向过程的执行者转化成了面向对象的指挥者
面向对象分析方法分析问题的思路和步骤:
根据问题需要,选择问题所针对的现实世界中的实体。
从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
类和对象
类和对象是面向对象的核心概念。
类是一类事物的描述,是抽象的、概念上的定义
对象是实际存在的该类事物的每个个体,因此也称为实例
属性 = 成员变量 = field = 域、字段
方法 = 成员方法 = 函数 = method
使用示例:
package com.xxx.java;
public class Person {
public static void main(String[] args) {
People p1 = new People();
//调用属性
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);
//调用方法
p1.eat();
p1.sleep();
p1.talk("Chinese");
People p2 = new People();
System.out.println(p2.name);
System.out.println(p2.isMale);
People p3 = p1;
System.out.println(p3.name); //name
p3.age = 10;
System.out.println(p1.age); //10
}
}
class People{
String name;
int age = 1;
boolean isMale;
public void eat() {
System.out.println("人可以吃饭");
}
public void sleep() {
System.out.println("人可以睡觉");
}
public void talk(String language) {
System.out.println("人可以说话,使用的是" + language);
}
}
对象的内存解析
堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在 Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。 局部变量表存放了编译期可知长度的 各种基本数据类型(boolean、byte、 char 、 short 、 int 、 float 、 long 、 double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内 存的首地址)。 方法执行完,自动释放。
方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
编译完源程序以后,生成一个或多个字节码文件。
我们使用JVM中的类的加载器和多个解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析
虚拟机栈,即为平时提到的栈结构,我们将局部变量存储在栈结构中。
堆,我们激将new出来的结构(比如:数组、对象)加载在堆空间中。补充:对象的属性(非static)加载在堆空间中
方法区:类的加载信息、常量池、静态域
属性
语法格式:
修饰符 数据类型 属性名 = 初始化值 ;
属性(成员变量) 与 局部变量的区别
相同点:
定义变量的格式相同
先声明,后使用
变量都有其对应的作用域
不同点:
在类中声明的位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected
局部变量:不可以使用权限修饰符。
默认初始化值的情况
属性:类的属性,根据其类型,都有默认初始化值
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0(或'\u0000')
布尔型(boolean):false
引用数据类型(类、接口、数组):null
局部变量:没有默认初始化值,在调用前,一定要显式赋值。
形参在调用时赋值即可
在内存中加载的位置:
属性:加载到堆空间中(非static)
局部变量:加载到栈空间中
变量 的分类补充:
方法
什么是方法(method、函数):
方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中 也称为函数或过程。
将功能封装为方法的目的是,可以实现代码重用,简化代码
Java里的方法不能独立存在,所有的方法必须定义在类里。
声明格式
修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
方法体程序代码
return 返回值;
}
返回值类型:
没有返回值:void。
有返回值,声明出返回值的类型。与方法体中“return 返回值”搭配使用
方法名:属于标识符,命名时遵循标识符命名规则和规范,“见名知意” 形参列表:可以包含零个,一个或多个参数。多个参数时,中间用“,”隔开
返回值:方法在执行完毕后返还给调用它的程序的数据。
方法的调用
方法通过方法名被调用,且只有被调用才会执行。
注意:
方法被调用一次,就会执行一次
没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
定义方法时,方法的结果应该返回给调用者,交由调用者处理。
方法中只能调用方法或属性,不可以在方法内部定义方法。
return关键字的使用:
使用范围:使用在方法中
作用:
结束方法
针对于有返回值类型的方法,使用"retuen 数据"返回所要的数据
注意点:return关键字后面不可以声明执行语句
练习
Person类
package com.xxx.exer;
public class Person {
String name;
int age;
int sex;
public void study() {
System.out.println("学习中");
}
public void showage() {
System.out.println(age);
}
public int addAge(int i) {
age += i;
return age;
}
}
测试
package com.xxx.exer;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Tom";
p1.age = 18;
p1.sex = 1;
p1.study();
p1.showage(); //18
p1.addAge(2);
p1.showage(); //20
Person p2 = new Person();
p2.showage();
p2.addAge(10);
p2.showage();
p1.showage(); //20
}
}
利用面向对象的编程方法,设计类Circle计算圆的面积。
package com.xxx.exer;
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
c1.radius = 2.1;
double area = c1.fingArea();
System.out.println(area);
}
}
class Circle{
double radius;
public double fingArea() {
double area = Math.PI * radius * radius;
return area;
}
}
3.1 编写程序,声明一个method方法,在方法中打印一个10*8 的*型矩形, 在main方法中调用该方法。
3.2 修改上一个程序,在method方法中,除打印一个10*8的*型矩形外,再 计算该矩形的面积,并将其作为方法返回值。在main方法中调用该方法, 接收返回的面积值并打印。
3.3 修改上一个程序,在method方法提供m和n两个参数,方法中打印一个 m*n的*型矩形,并计算该矩形的面积, 将其作为方法返回值。在main方法 中调用该方法,接收返回的面积值并打印。
package com.xxx.exer;
public class Exer3Test {
public static void main(String[] args) {
Exer3Test e1 = new Exer3Test();
int area = e1.method(12, 10);
System.out.println("面积为:" + area);
}
// 3.1
// public void method() {
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 8; j++) {
// System.out.print("* ");
// }
// System.out.println();
// }
// }
// 3.2
// public int method() {
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 8; j++) {
// System.out.print("* ");
// }
// System.out.println();
// }
// return 10 * 8;
// 3.3
public int method(int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print("* ");
}
System.out.println();
}
return m * n;
}
}
package com.xxx.exer;
public class Exer3Test {
public static void main(String[] args) {
Exer3Test e1 = new Exer3Test();
int area = e1.method(12, 10);
System.out.println("面积为:" + area);
}
// 3.1
// public void method() {
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 8; j++) {
// System.out.print("* ");
// }
// System.out.println();
// }
// }
// 3.2
// public int method() {
// for (int i = 0; i < 10; i++) {
// for (int j = 0; j < 8; j++) {
// System.out.print("* ");
// }
// System.out.println();
// }
// return 10 * 8;
// 3.3
public int method(int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print("* ");
}
System.out.println();
}
return m * n;
}
}
定义类Student,包含三个属性:学号number(int),年级state(int),成绩 score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
提示:
1) 生成随机数:Math.random(),返回值类型double;
2) 四舍五入取整:Math.round(double d),返回值类型long。
package com.xxx.exer;
public class StudentTest1 {
public static void main(String[] args) {
Student1[] stus = new Student1[20];
//赋值
for (int i = 0; i < stus.length; i++) {
stus[i] = new Student1();
stus[i].id = i + 1;
stus[i].state = (int) (Math.random() * (6 - 1 + 1) + 1);
stus[i].score = (int) (Math.random() * (100 - 0 + 1));
}
StudentTest1 test = new StudentTest1();
//遍历数组
test.print(stus);
System.out.println("****************");
//打印3年级的学生信息
test.searchStudent(stus, 5);
System.out.println("****************");
//冒泡排序学生成绩
test.sort(stus);
test.print(stus);
}
/**
*
* @Description 遍历Student1数组
* @author Alkaid
* @date 2022年7月28日上午12:38:58
* @param stus 遍历的数组
*/
public void print(Student1[] stus) {
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
}
/**
*
* @Description 查找Student1数组中指定年级的信息
* @author Alkaid
* @date 2022年7月28日上午12:35:19
* @param stus 遍历的数组
* @param state 查找的年级
*/
public void searchStudent(Student1[] stus, int state) {
for (int i = 0; i < stus.length; i++) {
if (stus[i].state == state) {
System.out.println(stus[i].info());
}
}
}
/**
*
* @Description 给Student1数组的成绩排序
* @author Alkaid
* @date 2022年7月28日上午12:38:11
* @param stus 遍历的数组
*/
public void sort (Student1[] stus) {
for (int i = 0; i < stus.length; i++) {
for (int j = 0; j < stus.length - 1 - i; j++) {
if (stus[j].score > stus[j + 1].score) {
// 交换数组的元素,而不是成绩
Student1 temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
}
}
class Student1 {
int id; // 学号
int state; // 年级
int score; // 成绩
public String info() {
String info = id + " 年级为:" + state + " 成绩为" + score;
return info;
}
}