Appearance
全局配置
Appearance
面向功能划分的软件结构
从上到下,按步执行
最小的粒度是方法
步骤繁琐,制约了软件的可维护性和可扩展性
代码一次成型,后续修改非常麻烦
把软件系统看成各种对象的集合
系统结构稳定
子系统相对独立
软件的可维护性,可扩展性强
面向过程编程关注点在于每一个细节,每一步的具体操作。 面向对象关注点在于整个事件的参与对象,将系统中的 参与者全部看成模块化的对象。 汽车 司机 北京 天津
面向对象程序设计(Object Oriented Programming)OOP 就是把世间万物都看成一个个对象, OOP是一种编程思想,思维模式,将程序中的所有参与者 模块化为对象,然后通过各种对象之间的相互作用关系来 完成程序的需求。
类是对象的模版,抽象化的对象。类是构成Java程序的单位,Java程序通过类来组织其结构,是指在开发期间,静态。 对象是Java程序在运行时的单位,运行期间的Java程序是通过多个对象之间的相互作用关系来完成需求,动态。
开发代码时,是通过编写类来完成程序的需求。 程序在运行期: 1.将编写好的类加载到JVM中,有了模版。 2.根据需求通过模版(类)来创建对应的对象,完成业务需求。
类是静态的,写完之后就存在于硬盘中。 对象是动态的,随着程序的运行而创建,同时随着程序的关闭而销毁。
JVM中类只有一份,对象有多份。
类的静态特征通过属性来描述 类的动态功能通过方法来描述
Scanner scanner = new Scanner(System.in); scanner.next(); Scanner scanner2 = new Scanner(System.in);
对象是类的具体实例化,具体化的类 scanner对象
每个对象的每个属性都拥有特定值。
属性是描述对象的特征的,是静态的 车的品牌,颜色,排量都是静态的,是属性
让车跑到北京,是动态的功能,程序中用方法来描述对象执行的操作,即其动态功能。
程序中使用方法来描述对象的动态功能,使用属性来描述对象的静态特征,所以,对象是由一组属性和方法构成,用来描述客观存在的一个实体。
与对象密不可分的另外一个概念是类。 类:具有相同属性和方法的一组对象的集合,类是对象 的抽象化描述,对象是类的具体实例。
虽然属性和方法是在类中定义的,但是如果需要访问属性或者调用方法,必须通过对象来完成,不能通过类来完成。
方法调用需要注意的事项: 参数的数据类型,顺序必须与类中方法定义时的列表一致。
对象和类是面向对象编程的核心。 所有的Java程序都是以类class为组织单元,一个Java文件就是一个类 真正执行程序是通过类的具体化对象来完成的。
public class 类名(首字母大写){ //定义属性,属性名符合驼峰式命名法 访问权限修饰符(public) 数据类型 属性名; 访问权限修饰符(public) 数据类型 属性名; ...
//定义方法,方法名符合驼峰式命名法
访问权限修饰符 返回值类型 方法名(参数列表){
方法体
}
...
}
public class Car {
//定义属性
public String color;
public int age;
public String brand;
public float width;
public float height;
//定义方法
public void start() {
System.out.println("将车开到北京");
}
public float getSpeed(float hour,float km) {
float speed = km/hour;
return speed;
}
public Car() {
}
public Car(String color,int age,String brand,float width,float height) {
this.color = color;
this.age = age;
this.brand = brand;
this.height = height;
this.width = width;
}
public Car(String brand) {
this.brand = brand;
}
}
通过调用类的构造函数/构造方法来创建 每一个类都有一个默认的无参构造方法,该方法不需要创建,由类自动生成。
构造方法语法: 访问权限修饰符 方法名/必须跟类名一模一样(参数列表){ 方法体 }
public class Test {
public static void main(String[] args) {
//创建一辆车,调用无参构造
Car car = new Car();
//给对象的属性赋值
car.age = 6;
car.brand = "奥迪";
car.color = "黑色";
car.height = 1.5f;
car.width = 2f;
//创建第二辆车,调用有参构造
Car car2 = new Car("红色",3,"宝马",2.2f,1.6f);
float speed = car.getSpeed(2f,200f);
float speed2 = car2.getSpeed(1.5f, 200f);
System.out.println(car.brand+"-"+car.color+"-时速:"+speed);
car.start();
System.out.println(car2.brand+"-"+car2.color+"-时速:"+speed2);
car2.start();
}
}
有参构造需要手动创建。 无参构造只创建对象,不完成对属性的赋值,需要在外部手动进行赋值。 有参构造边创建对象边完成对属性的赋值。
每个类都会有一个默认的无参构造, 如果手动在类中创建一个有参构造,会将默认的无参构造抹掉,如果一个类中有参和无参都需要,那么就必须手动将两种构造函数进行创建。
编写学员类,创建学员对象并输出相关信息 编写教师类,创建教师对象并输出相关信息
public class Student {
public int id;
public String name;
public int age;
public String gender;
public void show() {
System.out.println("学生信息如下:");
System.out.println("学号:"+id);
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("性别:"+gender);
}
public Student(int id, String name, int age, String gender) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
public Student() {
super();
}
public Student(int id, String gender) {
super();
this.id = id;
this.gender = gender;
}
}
public class Test2 {
public static void main(String[] args) {
Student student = new Student();
student.id = 1;
student.name = "张三";
student.age = 22;
student.gender = "男";
// student.show();
System.out.println("学生信息如下:");
System.out.println("学号:"+student.id);
System.out.println("姓名:"+student.name);
System.out.println("年龄:"+student.age);
System.out.println("性别:"+student.gender);
Student student2 = new Student(2,"李四",18,"女");
student2.show();
}
}
public class Teacher {
//属性:描述静态特征
public String name;
public int age;
public char gender;
//方法:描述动态功能
public void teach() {
System.out.println("老师上了一节课");
}
public String level(int score) {
/**
* score>=90:优秀
* 80<=score<90:良好
* 60<=score<80:中等
* score<60:差
*/
String result = "差";
if(score>=90) {
result = "优秀";
}else {
if(score>=80) {
result = "良好";
}else {
if(score>=60) {
result = "中等";
}
}
}
return result;
}
public void test(int num) {
num++;
System.out.println("方法内部:"+num);
}
public void test2(Teacher teacher) {
teacher = new Teacher();
System.out.println(teacher);
}
public Teacher(String name,int age,char gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public Teacher() {
}
}
null指空指针,用来描述内存地址的一个值,指空,不存在。 应用类型的变量可以赋值null, 基本数据类型的变量不能赋null
垃圾回收机制GC:是一个独立的巡查线程,GC是一个定时任务,隔一段时间执行一次。
基本数据在栈内存中开辟空间,同时直接将具体数值保存在栈中 引用类型在栈中开辟空间,同时在堆中创建对象,将堆内存的地址保存在栈中
基本数据类型传递是值,在方法内部改变变量的值,并不会影响到外部调用该方法时传入的变量值。
引用数据类型传递是地址
一个景区根据游人的年龄收取不同价格的门票。 编写游人类,根据年龄段决定门票价格并输出。
public class Person {
public String name;
public int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
public class Test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入游客姓名:");
String name = scanner.next();
System.out.print("请输入游客年龄:");
int age = scanner.nextInt();
Person person = new Person(name,age);
Admin admin = new Admin();
int price = admin.getPrice(person.age);
if(price == 0) {
System.out.println("游客"+person.name+"的年龄是"+person.age+",门票免费");
}else {
System.out.println("游客"+person.name+"的年龄是"+person.age+",应该收取的门票价格为"+price);
}
}
}
public class Admin {
public int getPrice(int age) {
int price = 0;
if(age >= 18) {
price = 20;
}
return price;
}
}
5位学员参加了Java知识竞赛,输出竞赛的平均成绩和最高成绩,定义一个工具类来完成。
public class ScoreTools {
public void result(int[] array) {
//1.求平均分
int sum = 0;
for(int score:array) {
sum += score;
}
float avg = sum/array.length;
//2.求最高分
int max = array[0];
for(int i = 1;i < array.length; i++) {
int score = array[i];
if(score > max) {
max = score;
}
}
System.out.println("平均分是:"+avg+"最高分是:"+max);
}
}
public class Test3 {
public static void main(String[] args) {
int[] array = {70,60,80,50,90};
int[] array2 = {66,77,99,33,78,89};
ScoreTools st = new ScoreTools();
st.result(array);
st.result(array2);
}
}
this可以来修饰类中的属性和方法,只能在方法中使用。 this.属性名 this.方法名(参数) this(参数):只能在构造方法中使用,不能在普通方法中使用,并且必须写在构造方法的第一行。
通常情况下,在类的方法中的具体代码,this可加可不加。 当方法中的参数和属性名一致时,通过参数名无法区分参数和属性时,需要通过this来修饰属性。 当方法中的参数和属性名不一致时,通过参数名可以区分参数和属性时,不需要加this。
用来描述现实生活中的具体事物的类我们把它叫做实体类,entity。
1.同一个类中 2.方法名相同 3.参数列表不同(个数或者数据类型不同) 4.与返回值,访问权限修饰符无关
package com.southwind.entity;
import java.util.Arrays;
public class Cal {
// 方法重载
public int add(int num1,int num2) {
return num1+num2;
}
public int add(int num1,int num 2,int num3) {
return num1+num2+num3;
}
public void add(int num1) {
}
// ### 动态参数
// 方法的定义:动态参数,参数列表中,数据类型后添加...
// 动态参数实质上是一个数组,当外部在调用方法时,
// 根据外部传入的参数个数来动态生成一个数组,记录所有的参数。
public int add(int... num) {
int sum = 0;
for(int i:num) {
sum += i;
}
return sum;
}
}
成员变量:定义在类中,方法体外的变量,属性 局部变量:定义在方法体中的变量
1.作用域不同:变量的可用范围 局部变量的作用域仅限于定义它的方法,出了方法就无法访问。 成员变量的作用域在整个类中都是可见的。 2.初始值不同 属性/成员变量都有一个初始值,初始值根据属性的数据类型来决定, 基本数据类型:byte int short long:0 double float:0.0 char:' ' boolean:false 引用类型:null(描述的是内存地址信息,表示空,不存在的地址)
局部变量没有初始值
同一个方法中,不允许有同名的局部变量。 在不同的方法中,可以存在同名的局部变量。
定义带参方法根据水果的不同,输出不同的水果汁。
public class Juicer {
public void getJuice(String fruit) {
System.out.println(fruit+"汁");
}
}
public class Test {
public static void main(String[] args) {
Juicer juicer = new Juicer();
juicer.getJuice("苹果");
}
}
使用带参方法实现学员信息管理,增加学员姓名,在保存了多个学生姓名的数组中,指定查找区间,查找某个学生姓名,并显示是否查找成功。
import java.util.Arrays;
import java.util.Scanner;
import com.southwind.entity.StudentTools;
public class StudentToolsTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StudentTools studentTools = new StudentTools();
for(int i = 0; i < 5; i++) {
System.out.print("请输入学生姓名:");
studentTools.array[i] = scanner.next();
}
System.out.println("本班学生列表");
for(String name:studentTools.array) {
System.out.print(name+"\t");
}
System.out.println("");
System.out.print("请输入开始查找的位置:");
int start = scanner.nextInt();
System.out.print("请输入结束查找的位置:");
int end = scanner.nextInt();
System.out.print("请输入查找的姓名:");
String name = scanner.next();
System.out.println(name);
boolean flag = studentTools.findName(start, end, name);
if(flag) {
System.out.println("找到了");
}else {
System.out.println("没有找到");
}
}
}
public class StudentTools {
public String[] array = new String[5];
public boolean findName(int start,int end,String name) {
for(int i = start;i<=end;i++) {
String val = array[i];
if(name.equals(val)) {
return true;
}
}
return false;
}
}
定义学员类,储存学员信息(属性:姓名,成绩。方法:显示个人成绩)编写修改成绩类,使用学员对象数组作参数,实现学员成绩修改。条件为如果学员成绩小于60,集体提高两分。最终输出修改成绩后,每个学员的成绩。
public class Student2 {
public String name;
public int score;
public void show() {
System.out.println(name+"的成绩是"+score);
}
public Student2(String name) {
super();
this.name = name;
}
}
import java.util.Scanner;
import com.southwind.entity.ScoreTools;
import com.southwind.entity.Student2;
public class Student2Test {
public static void main(String[] args) {
Student2 student1 = new Student2("张三");
Student2 student2 = new Student2("李四");
Student2 student3 = new Student2("王五");
Scanner scanner = new Scanner(System.in);
System.out.println(student1.name+"的成绩:");
student1.score = scanner.nextInt();
System.out.println(student2.name+"的成绩:");
student2.score = scanner.nextInt();
System.out.println(student3.name+"的成绩:");
student3.score = scanner.nextInt();
Student2[] array = {student1,student2,student3};
ScoreTools scoreTools = new ScoreTools();
System.out.println("修改之前的学生成绩:");
for(Student2 stu:array) {
stu.show();
}
scoreTools.update(array);
System.out.println("修改之后的学生成绩:");
for(Student2 stu:array) {
stu.show();
}
}
}
public class ScoreTools {
public void update(Student2[] array) {
for(Student2 stu:array) {
if(stu.score < 60) {
for(Student2 stu2:array) {
stu2.score += 2;
}
}
}
}
public void getResult(int[] array) {
int sum = 0;
int max = array[0];
for(int score:array) {
sum += score;
if(score > max) {
max = score;
}
}
float avg = sum/array.length;
System.out.println("平均成绩:"+avg+",最高分是:"+max);
}
}
按照方法重载定义,实现简易计算。
public class Cal {
public int add(int num1,int num2) {
return num1+num2;
}
public float add(float num1,float num2,float num3) {
return num1+num2+num3;
}
}
public class CalTest {
public static void main(String[] args) {
Cal cal = new Cal();
System.out.println(cal.add(3,3));
System.out.println(cal.add(1.5f, 2.6f,3.3f));
}
}