面向对象
面向对象
一、IDEA的一些基本使用
网址:IntelliJ IDEA – 领先的 Java 和 Kotlin IDE (jetbrains.com)
创建IDEA工程:
- 创建一个空的工程
设置主题和字体设置
Alt+Shift+Up/Down | 上/下移一行 |
---|---|
Ctrl+D | 复制行 |
Ctrl+X | 删除行 |
Ctrl+Y | 删除当前行 |
Ctrl+Shift+U | 大小写转化 |
Shift+Enter | 向下插入新行 |
Ctrl+Shift+Space | 自动补全代码 |
Alt+Insert | 以生成构造器/Getter/Setter等 |
二、面对对象
什么的面向对象:
用程序去模拟现实世界,因为这是最直观的。
1.什么是对象
万物皆对象,是真正存在的事物
是对类的一个具象,是一个实体。
2.什么是类
-
具有共性的一组事物的抽象(模板),叫做类,是一个概念而不是具体的事物。
-
通常是对一组具有相同特性的对象,将其共性抽取出来
-
在程序当中:类是一个文件
3.对象的构成
-
特性(属性):可以落于纸面,可以进行量化,可以描述
-
行为(方法):用于表示过程,行为
没有任何一个事物可以脱离场景独立存在,类的扩展可以在水平(同一类型,不同的展示)扩展,也可以在垂直(上级类型/下级类型)扩展
4.类的创建
- IDEA当中创建模块
语法:
使用关键字:class
public class Person{
}
类的成员
public class Person {
//属性
public int id;
public String name;
public int sex;
public int age;
//方法
public void say(){
System.out.println("我真帅");
}
public void sleep(){
System.out.println("在哪里跌倒,就在哪里睡着");
}
}
- 属性(成员变量)的结构:
- 访问修饰符 属性类型 属性名
- 方法(成员方法)的结构
- 访问修饰符 返回值类型(void) 方法名(方法体)
注意:
方法发书写非常的灵活,这里仅仅是演示方法的使用
5.创建对象
语法:
类名 对象名 = new 类名/构造方法名();
案例
public class Main {
public static void main(String[] args) {
//对象的创建
Person a = new Person();
a.id = 1;
a.name = "df";
a.sex = 1;
a.age = 18;
Person b = new Person();
b.id = 2;
b.name = "shmily";
b.sex = 0;
b.age = 16;
System.out.println("df的姓名"+a.name);
System.out.println("shmily的姓名"+b.name);
}
}
- 给对象的属性赋值
语法:
对象名.属性名 = 值;
- 从对象的属性取值
语法:
变量类型 变量名 = 对象名.属性名;
- 方法的调用
public class Main2 {
public static void main(String[] args) {
//对象的创建
Person a = new Person();
a.say();
Person b = new Person();
b.say();
}
}
语法:
对象名.方法名();
注意:
任何对象,如果没有实例化,则直接调用时,会出现空指针异常。
Exception in thread "main" java.lang.NullPointerException
什么是实例化:
new出来的这个部分就是实例,new的这个行为叫做实例化
匿名实例化:
public class Main2 {
public static void main(String[] args) {
//对象的创建
Person df = new Person();
//匿名创建对象
new Person();
new Person().name = "DF";//匿名属性赋值
new Person().say();//匿名方法调用
}
}
注意:
1.属于一次性消耗
2.只要看见new关键字,就是一个新的对象!
课间作业
- 在教室中找素材创建10个类
- 为每一个类,赋予足够多的属性和方法(10属性,5个方法)
- 为每个类创建其对象,并赋予属性值,同时调用所有的方法
Fan.java
package com.mine.student;
public class Fan {
//风扇
public int fanId;
public String fanName;
public String color;
public String fanLong;
public String fanWide;
public String fanHigh;
public double fanPrice;
public String fanMaterial;
public String factoryTime;
public double serviceLife;
public void open() {
System.out.println("风扇开始旋转~~~");
}
public void close() {
System.out.println("风扇开始停止~~~");
}
public void speedUp() {
System.out.println("调快风扇转速~~~");
}
public void speedDown() {
System.out.println("调慢风扇转速~~~");
}
public void rollback() {
System.out.println("风扇开始逆时针旋转~~~");
}
}
Cup.java
package com.mine.student;
public class Cup {
//杯子
public int cupId;
public String cupName;
public String color;
public double cupLong;
public double cupWide;
public double cupHigh;
public String cupMaterial;
public String cupCapacity;
public String cupSpecification;
public double cupPrice;
public void fillWater(){
System.out.println("装水~~~");
}
public void tea(){
System.out.println("泡茶~~~");
}
public void bubbleGoji(){
System.out.println("泡枸杞~~~");
}
public void driedMilk(){
System.out.println("泡奶粉~~~");
}
public void coffee(){
System.out.println("泡咖啡~~~");
}
}
Main.java
package com.mine.student;
public class Main {
public static void main(String[] args) {
//风扇
Fan fan = new Fan();
fan.fanId = 1;
fan.fanName = "风扇";
fan.color = "pink";
fan.fanPrice = 66.6;
fan.fanLong = "50cm";
fan.fanWide = "30cm";
fan.fanHigh = "1cm";
fan.factoryTime = "2022-10-18";
fan.fanMaterial ="金属";
System.out.println("编号:"+fan.fanId+",名字:"+fan.fanName+",颜色:"+fan.color+",价格:"+fan.fanPrice);
String str = String.format("%s的编号是:%d,颜色%s,价格%f,长:%s,宽:%s,高:%s,出厂时间:%s,材质:%s",fan.fanName,
fan.fanId,fan.color,fan.fanPrice,fan.fanLong,fan.fanWide,fan.fanHigh,fan.factoryTime,fan.fanMaterial);
System.out.println(str);
//茶杯
Cup cup = new Cup();
cup.cupId = 2;
cup.cupName = "SUPER";
cup.color = "Black";
cup.cupMaterial = "304不锈钢";
cup.cupPrice = 99.99;
System.out.println("编号:"+cup.cupId+",名字:"+cup.cupName+",颜色:"+cup.color+",价格:"+cup.cupPrice+",材质:"+cup.cupMaterial);
}
}
结果:
编号:1,名字:风扇,颜色:pink,价格:66.6
风扇的编号是:1,颜色pink,价格66.600000,长:50cm,宽:30cm,高:1cm,出厂时间:2022-10-18,材质:金属
编号:2,名字:SUPER,颜色:Black,价格:99.99,材质:304不锈钢
三、方法
什么是方法:
可以实现特定功能的代码,可以重复使用。
我们不需要知道方法的内部是如何执行的,我们只需要知道,我应该给这个方法提供什么样的参数,以及该方法可以返回给我的返回值
1.定义语法
访问修饰符 返回值类型 方法名 (形参列表){
方法体
return 返回值
}
2.返回值
两个大类:
- void:没有返回值
public class Person {
public void say(){
System.out.println("巴拉巴拉");
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.say();//调用就行,不需要返回任何东西
}
}
- 有返回值(返回值类型)
注意:
返回值的类型可以任意,但是注意,这里是类型,不是值。
使用关键字return返回具体的值。
public class Person {
public String say(){
return "巴拉巴拉";//返回的值,必须和声明的返回值类型保持一致
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
String result = p.say();//调用者调用方法得到的结果,可以使用相同类型的变量承接
}
}
返回值的类型和返回的值,以及调用者用于承接结果的变量类型都需要保持一致
3.return关键字
return在有返回值的情况下,必须存在,且只能执行一次
在没有返回值的情况下,可有可没有
案例:
- 在void返回值类型的情况下
public class Person {
public void say(){
int i = 1;
if(i > 0){
System.out.println("在这里返回,终止程序继续运行");
return;//如果执行了,方法立即终止
}
System.out.println("这是后续内容");
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.say();
}
}
结果:
在这里返回,终止程序继续运行
- 如果有返回值
public class Person {
public void say(){
int i = 1;
if(i > 0){
System.out.println("在这里返回,终止程序继续运行");
return;//如果执行了,方法立即终止
}
System.out.println("这是后续内容");
}
public int run1(){
int i = 1;
if(i > 0){
System.out.println("作为一个分支1");
return 100;//无法被计算机确定,肯定能被执行
}else{
System.out.println("作为一个分支2");
return 200;//如果加上else则至少有一个return会被执行
}
// System.out.println("这是后续内容");//这里根本无法被执行到
}
public int run2(){
int i = 1;
if(i > 0){
System.out.println("作为一个分支1");
return 100;//无法被计算机确定,肯定能被执行
}
System.out.println("这是后续内容");
return 200;//这个return在排除其他任何一个情况后,确保最终一定会有一个return被执行
}
}
只要返回值类型不是void,那么必须要提供返回值,即执行return语句,且只能执行一次。
4.方法的参数
作用:往方法内部传递数据
- 形参
- 申明语法:
- 1.可以有0-n个,不同的参数之间,使用逗号分隔
- 2.必须是某个数据类型,数据类型包含基本数据类型和引用数据类型,不可以是具体的值
- 申明语法:
案例:
package com.mine.demo1;
public class Cat {
public void eat(int n,String food){
/*
参数名可以根据需要任意取,参数名和调用方没有关系
*/
}
}
方法的参数在方法体当中,可以当做一个普通的,已经被赋值了的变量的使用
package com.mine.demo1;
public class Cat {
public void eat(int n,String food){
/*
参数名可以根据需要任意取,参数名和调用方没有关系
参数直接当成普通变量使用
*/
System.out.println(String.format("咪咪今天吃了%dkg的%s",n,food));
}
}
-
实参
- 1.调用方法时,向方法传递的具体的数据的值
- 2.形参和实参在调用时的数量、顺序、类型必须保持一致
案例:
package com.mine.demo1; public class Main { public static void main(String[] args) { Cat cat = new Cat(); cat.eat(10,"小鱼干"); } } 结果: 咪咪今天吃了10kg的小鱼干
-
一个特殊的参数类型,不定长参数,即改方法的实参数量不固定
-
形参语法
package com.mine.demo1; public class Cat { // public void eat(int n,String food){ // System.out.println(String.format("咪咪今天吃了%dkg的%s",n,food)); // } //相同的作用,在申明时比数组更加简练 public void eat(String ... foods){ //当做普通数组使用 for(int i =0;i < foods.length;i++){ System.out.println(foods[i]); } } }
-
实参语法
package com.mine.demo1; public class Main { public static void main(String[] args) { Cat cat = new Cat(); //cat.eat(10,"小鱼干"); cat.eat("小鱼干,小虾米,猫粮");//可以传递0-n个该类型的实参 } }
-
注意:
不定长参数,只能在形参列表的末尾,且只能有一个
-
5.地址传参
地址赋值
案例:
package com.mine.demo2;
public class Cat {
public String name;
}
package com.mine.demo2;
public class Main {
public static void main(String[] args) {
Cat cat1 = new Cat();
Cat cat2 = new Cat();
System.out.println(cat1);
System.out.println(cat2);
}
}
结果:
com.mine.demo2.Cat@4554617c
com.mine.demo2.Cat@74a14482
结论:
引用数据类型在进行相互赋值时,传递的是内存地址
通过方法传参,传递地址
案例:
package com.mine.demo2;
public class Cat {
public String name;
}
package com.mine.demo2;
public class Master {
public void feed(Cat cat){
System.out.println(String.format("方法内的内存地址:%s",cat));
cat.name = "小猫2";
System.out.println(String.format("cat的name2:%s",cat.name));
}
}
package com.mine.demo2;
public class Main {
public static void main(String[] args) {
Cat cat1 = new Cat();
// Cat cat2 = new Cat();
// System.out.println(cat1);
// System.out.println(cat2);
Master master = new Master();
cat1.name = "小猫1";
System.out.println(String.format("传递前的内存地址:%s",cat1));
System.out.println(String.format("cat name1:%s",cat1.name));
master.feed(cat1);
System.out.println(String.format("传递后的内存地址:%s",cat1));
System.out.println(String.format("cat name2:%s",cat1.name));
}
}
结果:
传递前的内存地址:com.mine.demo2.Cat@5cad8086
cat name1:小猫1
方法内的内存地址:com.mine.demo2.Cat@5cad8086
cat的name2:小猫2
传递后的内存地址:com.mine.demo2.Cat@5cad8086
cat name2:小猫2
在方法内部更换对象地址,不影响原本改对象的引用关系
- 引用对象内存地址的传递,是需要一个赋值这么个过程的(赋值我才能把地址给你)
- 引用当中的数据修改
案例:
package com.mine.demo2;
public class Cat {
public String name;
}
package com.mine.demo2;
public class Master {
/*
每一个方法都有一个独立的方法栈,在该方法栈当中申请的新的内存地址,对其外部调用没有任何影响
*/
public Cat feed(Cat cat2){
cat2 = new Cat();
System.out.println(String.format("2.方法内的内存地址:%s",cat2));
return cat2;
}
}
package com.mine.demo2;
public class Main {
public static void main(String[] args) {
Cat cat1 = new Cat();
Master master = new Master();
cat1.name = "小猫1";
System.out.println(String.format("1.传递前的cat2地址:%s",cat1));
Cat cat2 = master.feed(cat1);
System.out.println(String.format("3.传递后cat2的内存地址:%s",cat1));
System.out.println(String.format("4.传递后新建的cat2的内存地址:%s",cat2));
}
}
结果:
1.传递前的cat2地址:com.mine.demo2.Cat@5cad8086 【传参前】
2.方法内的内存地址:com.mine.demo2.Cat@6e0be858 【方法内部更换的内存引用】
3.传递后cat2的内存地址:com.mine.demo2.Cat@5cad8086 【对原本的引用没有任何影响】
4.传递后新建的cat2的内存地址:com.mine.demo2.Cat@6e0be858 【要获取方法内的新的引用,可以通过返回值来获取】
6.作用域
全局变量:
- 全局变量直接申明在类当中
- 全局变量有默认值:整数(0),浮点数(0.0),字符(空格),布尔类型(false),引用类型(null)
- 在整个类当中,所有区域,所有方法都可以使用,整个类共享
- 可以有访问修饰符
- 全局变量的基本数据类型在堆当中
public class Person{
//全局变量:申明在类中
public int id;
public String name;
public Dog dog;
}
局部变量:
- 在方法当中被使用
- 包含:
- 在方法当中申明的变量
- 在参数列表当中申明的形参
- 局部变量必须赋初值才可以使用
- 局部变量不可以使用访问修饰符
- 基本数据类型在栈当中
注意:当局部变量和全局变量重名时,优先使用局部变量
了解:使用this关键字
public class Person{
public int i = 1;
public void feed(){
int i = 2;
System.out.println(this.i); //使用的是全局变量i = 1
}
}
方法的调用区域:
内部调用:在类的内部,调用自身的方法
语法:直接调用,即方法名(实参);
public class Test {
public void fun1(){
System.out.println("fun1");
fun2();//类的内部调用,直接调用
fun3();
}
public void fun2(){
System.out.println("fun2");
}
public void fun3(){
System.out.println("fun3");
}
}
外部调用:在类的外部,需要通过创建对象的方式进行调用
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.fun1();
test.fun2();
test.fun3();
}
}
调用区域:
package com.mine.demo08;
//fun();//不允许
public class Test {
// fun();//不允许
public int i = fun();//允许
public int fun(){
return 100;
}
}
//fun();//不允许
课堂练习
以面向对象的思路完成学生考试成绩录入系统
Student.java
package com.mine.student;
public class Student {
/**
* 学生学号
*/
public int stuId;
/**
* 学生名字
*/
public String stuName;
/**
* 学生成绩
*/
public String stuScore;
}
SystemUtil.java
package com.mine.student;
public class SystemUtil {
/**
* 学生成绩排序
*/
public void sortScore(){
}
}
ExamSystem.java
package com.mine.student;
import java.util.Scanner;
public class ExamSystem {
/**
* 声明scanner对象
*/
public Scanner scanner;
/**
* 初始化
*/
public void init(){
scanner = new Scanner(System.in);
System.out.println("初始化完成!");
}
/**
* 选择功能
*/
public int selectOption(){
System.out.println("请选择1.录入学生成绩\t2.展示学生成绩\t3.退出系统");
return scanner.nextInt();
}
/**
* 录入学生成绩
*/
public void insertScore(){
System.out.println("学生成绩录入成功!");
}
/**
* 展示学生成绩
*/
public void showScore(){
System.out.println("学生成绩展示成功!");
}
/**
* 退出系统
*/
public void exit(){
System.out.println("系统退出成功!");
}
}
Main.java
package com.mine.student;
public class Main {
public static void main(String[] args) {
ExamSystem system = new ExamSystem();
System.out.println("欢迎使用学生管理系统!");
system.init();
boolean flag = true;
while(flag){
int num =system.selectOption();
switch (num){
case 1:
system.insertScore();
break;
case 2:
system.showScore();
break;
case 3:
system.exit();
flag = false;
break;
default:
System.out.println("输入错误!");
}
}
}
}