2025年面向对象编程(全)

面向对象编程(全)面向对象编程 第一章 面向对象编程 1 1 基于面向对象的开发过程 基本面向对象分析 OOA Object Oriented Analysis 基本面向对象设计 OOD Object Oriented Design 基于面向对象编程 OOP Object Oriented

大家好,我是讯享网,很高兴认识大家。

面向对象编程

第一章 面向对象编程

1.1基于面向对象的开发过程

基本面向对象分析 OOA (Object Oriented Analysis)

基本面向对象设计 OOD(Object Oriented Design)

基于面向对象编程 OOP (Object Oriented Programming)

1.2 面向过程和面向对象

面向过程开发 : 将系统按照事物的发展顺序设计,每个过程用函数体现(c语言 ,核心是函数)

面向对象开发 : 将系统当中存在事物归类,按照类别体现(java语言 ,核心是对象)

超市系统:

面向过程 : 1. 登录系统 2. 客户购买 3.收银 4. 进货 5. 退出 小红超市买苹果,付钱

面向对象 : 1.客户类 2. 商家类 3. 商品类 4. 结算订单

思考:五子棋游戏: 白方 黑方 棋盘系统类

1.3 面向对象的优势

1.最大的好处就是:代码重用 (避免代码的冗余)

2.不同的分析可以有不同的实现方式

1.4 面向对象的核心

面向对象的核心是类(对象)

类: 一类事物的抽象,概括统一说法 文具,抽象的说法

对象: 实际存在的个体 文具盒,具体的事物

学生类/张雨

老师类/小喵

动物类 /猫

类 : 类是对象的抽象说法,不占内存 ,分析写代码时候抽象的

对象 : 对象是类的具体化说法,占内存, 需要将类付诸于具体的对象的

注意:

先规划出类,设计类的特征和行为,将来把类的对象创建出来

1.5 类的构成

1.5.1属性

用于描述一类事物的特征,特点,如 学生的学号,性别,年龄....

1.5.2方法

用于描述一类事物的行为,动作和能力。 如学生吃饭,学习,运动....

类的语法规则:

 控制权限  class  类名{   //属性     //方法    }

讯享网

注意:

  1. 控制权限 public 不加 ; 只有一个加public 的,和文件名相同
  2. class 声明类的关键字
  3. 类名 : 合法标识符 首字母大写 含义 不能是关键字

属性的语法规则:

讯享网 控制权限    数据类型   属性名 [=初始值];

注意:

  1. 控制权限 public
  2. 数据类型 : 基本+引用类型
  3. 属性名: 同变量名
  4. 属性可以给初始值,也可以不给,有默认值: int 0 double 0.0 char \u0000 boolean false 引用 null

方法的语法规则:(重点

 控制权限   [修饰符]   返回类型   方法名(形参类型  形参变量,形参类型  形参变量){      方法体;     [return  返回值];  }

注意:

  1. 控制权限 public
  2. 返回类型 :
    1. 有返回类型 指定一种类型:int double String... ,指定返回值方法的最后一定要有return 值;

      return 的值只能是一个,返回给调用者

    2. 无返回类型 void
  3. 方法名 同变量名
  4. 方法的参数:
    1. 方法声明时 形参 外部传入数据 ,必须逐一指明类型
    2. 方法调用时 实参
讯享网 public class Student {   //属性     public int sno ;//学号      public String sName;//姓名   public int age = 20; //年龄   public double weight; //体重     /   * 吃饭   */   public void eat() {   System.out.println(sName + "在吃饭");   }   /   * 跑步:返回跑公里数   */     public int run() {   System.out.println(sName + "在跑步");   //return "公里:" + 10 + ";卡路里: " + 300;   return 10;   }   /   * 算题   */   public int calc(int a,int b) {     return a + b;   }  }

练习:定义一个动物类

属性: 名字,年龄,品种

方法:

1.睡觉: 返回睡几小时

2.吃饭 : 传入吃的东西,返回吃了多少克

3.跑动 :无参数 无返回

 public class Animal {   public String name;   public int age;   public String type;     public double sleep() {   return 10;   }     public double eat(String food) {   System.out.println(name + "吃" + food);   //返回吃掉   return 5.5;   }     public void run() {   System.out.println(name + "在跑动");   }  }

1.5.3 类图
讯享网

 

讯享网 package com.qf.oop;  ​  public class Player {   public char gender;//性别   public String name;//角色名   public int level; //等级        //键盘按键行走,根据性别决定速度   public String run(char code) {   //确定速度   double speed = 0;   if(gender == '男') {   speed =  60;   }   else if(gender == '女') {   speed =  40;   }   //确定方向   if(code == 'a') {   return name + "向左以" + speed + "速度奔跑";   }else if(code == 's') {   return name + "向下以" + speed + "速度奔跑";   }else if(code == 'd') {   return name + "向右以" + speed + "速度奔跑";   }else if(code == 'w') {   return name + "向上以" + speed + "速度奔跑";   }else {   return name + "原地不动";   }   }     //攻击,传入武器   public void fight(String weapon) {   System.out.println(name + "使用" + weapon + "战斗");   }  }

1.5.4 对象的创建

类只是从设计的角度分析,如果使用类,必须创建该类的对象,真正的对象实例(堆中开辟内存)

 类名  对象名  =  new  类名();

讯享网 Player monkey = new Player();

当类创建了对象,在堆中开辟内存,根据类中定义的属性个数决定开辟,堆中分配所有属性。

 

1.5.5 对象成员的访问

成员: 属性和方法

属性的调用:

 对象名.属性名 //获取  对象名.属性名 = 值; //赋值

方法的调用:

讯享网 数据类型  返回值  = 对象名.方法名(实参1,实参2...);//有返回值的方法  ​  对象名.方法名(实参1,实参2...); //没有返回值

注意:

  1. 当调用方法时,如果类中方法设定过形参,调用的时候传入实参

    形参: 类中方法声明定义的参数 , 形参是变量

    实参: 对象调用方法时候的参数, 实参是数值

    实参把值赋给形参, 形参 = 实参; 个数一致,类型一致,顺序一致

  2. 当方法内部设定了返回值,将值还给调用方法的位置,调用位置需要接收返回值

 //类里定义位置  //weapon是形参  public void fight(String weapon) {   System.out.println(name + "使用" + weapon + "战斗");  }  ​  ​  //对象调用位置  monkey.fight("金箍棒");//实参  ​

玩家测试类:

讯享网 public class TestPlayer {   public static void main(String[] args) {   //创建玩家对象   Player monkey = new Player();   //System.out.println(monkey);//地址   //System.out.println(monkey.name);//null   //System.out.println(monkey.level);//0   //System.out.println(monkey.gender);//\u0000     monkey.name = "美猴王";   monkey.level = 2;   monkey.gender = '男';     System.out.println(monkey.name);   System.out.println(monkey.level);   System.out.println(monkey.gender);     monkey.fight("金箍棒");   System.out.println("啊哈哈哈哈哈");   }  }

1.5.6 变量的分类

变量分为两大类: 全局变量(属性),局部变量。

全局变量 局部变量
位置 类里方法外 方法里,方法的形参
权限 必须有权限 没有权限
默认值 有默认值 没有默认值
作用范围 整个类{ } 所在的{ }
生命周期 对象创建时产生,对象销毁消失 语句块{ }
内存 堆(对象实例,大块空间) 栈(临时变量存储)

注意:

  1. 当全局变量和局部变量重名,局部变量会将全局变量覆盖
  2. 如果在方法中想要调用被覆盖的属性,this.属性

1.5.7 数组和对象结合

1.对象的属性是数组类型

 public class Student {   public String name;   public String tel;   public int no;     //三门成绩   public double[] scores ;     /   * 返回平均成绩   */   public double getAvg() {   double sum = 0;   for (int i = 0; i < scores.length; i++) {   sum += scores[i];   }   return sum / scores.length;   }   public void state(int day) {   if(day >= 1 && day <= 5) {   System.out.println("好好上课");   }else if(day == 6) {   System.out.println("休息");   }else if(day == 7) {   System.out.println("打游戏");   }else {   System.out.println("非法日期");   }   }  ​     public String info() {   return "Student [name=" + name + ", tel=" + tel + ", no=" + no + ", scores=" + Arrays.toString(scores) + "]";   }  }

测试类:

讯享网 public class TestStudent {   public static void main(String[] args) {   Student s = new Student();   s.name = "老沈";   s.no = 110;   s.tel = "";     s.scores = new double[] {87,100,69};     double avg = s.getAvg();   System.out.println(s.info());   System.out.println("平均分数" + avg);   s.state(2);   }  }

2.数组的元素是对象类型

对象数组: 数组的元素是一个个对象

语法:

 类 []  数组名  =  new 类[大小];

讯享网 public class Goods {   public int no;   public String name;   public double price;   public int counts;  }  ​
 public class TestGoods {   public static void main(String[] args) {   //定义一个商品数组   Goods [] goods = new Goods[3];   Scanner sc = new Scanner(System.in);   //动态赋值   for (int i = 0; i < goods.length; i++) {   goods[i] = new Goods();   System.out.println("请输入商品名称");   goods[i].name = sc.next();   System.out.println("请输入商品价格");   goods[i].price = sc.nextDouble();   System.out.println("请输入商品编号");   goods[i].no = sc.nextInt();   System.out.println("请输入商品库存");   goods[i].counts = sc.nextInt();   }     //数组遍历     for (Goods g : goods) {   System.out.println(g.name + "," + g.price);   }     //获得最高价格的商品   double max = 0;   int index = -1;   for (int i = 0; i < goods.length; i++) {   if(max < goods[i].price) {   max = goods[i].price;   index = i;   }   }   System.out.println(goods[index].name);  ​          //控制台接收一个水果名,数组查找是否存在 equals()   int index = -1;   System.out.println("请输入您需要查找的水果名:");     String n = sc.next();   for (int i = 0; i < goods.length; i++) {   if(goods[i].name.equals(n)) {   index = i;   break;   }   }   if(index == -1) {   System.out.println("没有该商品");   }else {   System.out.println(goods[index].name + "," + goods[index].price);   }   }  }

 

1.5.8 方法的调用

1.5.8.1 调用方式

  1. 对象调用,类创建出对象后,通过对象调用
讯享网 public class Student {     public String name;     public void study() {   System.out.println(name + "在认真学习");   }      public static void main(String[] args) {   Student s = new Student();   s.name = "张雨";   //对象调用方法   s.study();   }  }

2.类中的方法互相调用

 public class Student {     public String name;   //学习方法   public void study() {          //听歌   music();   System.out.println(name + "在认真学习");     }   //听歌   public void music() {   System.out.println(name + "在听音乐");   }  }  ​

注意: 当a方法调用b方法的时候,先执行b,b执行完,再回来执行a。

讯享网 public class Test {   public void a() {   b();   System.out.println("a");   }   public void b() {   c();   System.out.println("b");   }   public void c() {     System.out.println("c");   }   public static void main(String[] args) {   new Test().a(); // c b a   }  }

设定返回值:

 public void a() {   b();   System.out.println("a");   }   public void b() {     System.out.println("b");   System.out.println("2" + c());   }     public int c() {   System.out.println("c");   return 2;   } // b c 22 a 

  1. 递归调用(了解)

方法自己调用自己,递归调用必须要有一个结束条件,否则会造成死递归,堆栈溢出。

讯享网 public class Num {     /   * 求阶乘   *   * 1! = 1   * 2! = 1! * 2   * 3! = 2! * 3   * ..   * n! = (n - 1)! * n   */   public int getJc(int n) {   if(n == 1) {   return 1;   }          return getJc(n - 1) * n;   }     public static void main(String[] args) {   Num n = new Num();   int res = n.getJc(3);   System.out.println(res);   }  }

综合练习:

 public class ScoreCalc{   public int[] scores ;   public double sum() {   double sum = 0;   for (int i = 0; i < scores.length; i++) {   sum += scores[i];   }   return sum;   }     public double avg() {   return sum() / scores.length;   }     public void print() {   System.out.println("平均成绩:" + avg());   }  ​  }  /   测试  */  public class TestScore {   public static void main(String[] args) {   ScoreCalc c = new ScoreCalc();   c.scores = new int[] {100,67,74};   c.print();   }  }  ​

1.5.8.2 方法参数个数

  1. 方法的重载: 展示方法的多样化(两个以上)

满足条件:

讯享网1. 方法名相同 2. 方法的参数一定不同: 个数,类型,顺序 3. 实参自动调用对应形参的方法
 public class Student {     /   * 计算两个数的和   */   public int sum(int a,int b) {   return a + b;   }     /   * 计算三个数的和   */   public int sum(int a,int b,int c) {   return a + b + c;   }     public double sum(double a,double b) {   return a + b;   }   public double sum(double a,int b) {   return a + b;   }   public double sum(int a,double b) {   return a + b;   }   //相同的方法  // public int sum(int c,int d) {  //  // }      //测试      sum(1,2,3);  }

2.可变长参数(jdk5+)

用于设计方法的时候,不限制参数个数

讯享网 控制权限  返回值  方法名([参数类型 参数变量 , ] 数据类型...可变长参数变量){    ​   方法体;   return 值;  }

注意:

  1. 可变长参数一定放在参数列表的最后
  2. 当定义了可变长参数,传递的实参个数可以不固定
  3. 在方法中,将可变长参数当作数组使用

 public class Student {   //可变长参数的方法,p参数变量   public int sum(int ...p) {   int sum = 0;   for (int i = 0; i < p.length; i++) {   sum += p[i];   }   return sum;   }     public static void main(String[] args) {   Student s2 = new Student();          //任意个数的实参   int res = s2.sum(1,2,3,4,5,10);   System.out.println(res);   }  }

1.5.8.3 方法调用参数传递

当调用方法的时候,传递实参,实参赋值给形参

1.基本数据类型 : 传递的是数值

2.引用数据类型 : 传递的是地址(引用)

讯享网 public class Param1 {   public static void change(int a,int[]b,Person p) {   a = 10;   //b = new int[] {2,4,6,8};   b[0] = 88;   p.face = "哭唧唧";   }   public static void main(String[] args) {   int a = 20;   int [] b = {1,2,3,4};   Person p = new Person();   p.face = "笑嘻嘻";   change(a,b,p);   System.out.println(a);// 20   System.out.println(Arrays.toString(b)); //88 2 3 4   System.out.println(p.face); // 哭唧唧   }  }

堆栈图:

 

方法传参案例:

 public class Param2 {  ​   public static void change(int x,int y,Birth b,String s) {   //交换   int temp = x;   x = y;   y = temp;   System.out.println(x + "," + y);// 200 100   b = new Birth();   b.date = 30;   s = "abc";   }     public static void main(String[] args) {   int x = 100, y = 200;   Birth b = new Birth();   b.year = 2002;   b.month = 5;   b.date = 9;   //字符串类型传参比较特殊   String a = "123";   change(x,y,b,a);   System.out.println(x + "," + y);// 100 200   System.out.println(b.date);//9   System.out.println(a);//123   }  }  public class Birth {   public int year;   public int month;   public int date;  }  ​

1.6 构造方法

又叫做构造器,类中一种特殊的方法。(重点)

作用:

能够在创建对象的时候,给属性直接赋值(属性初始化)。

语法:

讯享网控制权限 类名(形参类型 变量, 形参类型 变量2...){ 方法体(给属性赋值) }

注意:

  1. 没有方法的返回声明
  2. 构造方法的方法名是类名

无参数的构造器:

 public Birth() {   System.out.println("创建了生日对象");  }

有参数的构造方法:

讯享网 public Birth(int year,int month,int date) {   this.year = year;   this.month = month;   this.date = date;   }

构造方法的调用者 : JVM 自动调用

构造方法的调用时机: new对象

构造方法调用次数: 1次

构造方法的分类:

  1. 默认构造方法 当不定义构造方法的时候,系统会自动创建一个默认的构造方法
 public 类(){    }
讯享网 2. 当手动定义了构造方法,默认的无参构造方法就被覆盖。因此,当创建构造方法的时候,一定加上无参构造。  3. 构造方法可以实现重载: 根据方法的参数不同实现

构造方法和普通方法的区别:

构造方法 普通方法
返回类型 无返回声明 必须加声明 void
调用方式 JVM 对象.方法()
作用 初始化属性 自定义
调用时间点 创建对象的时new 自定义

类中成员: 属性 + 方法+ 构造方法

思考: 类中普通方法是否可以是类名作为方法名? 可以,不推荐。 声明返回值类型

第二章 面向对象三大基本特性

面向对象的三大基本特性: 封装性 , 继承性 ,多态性

1,封装性 信息隐藏,数据包装 ,安全性

2,继承性 代码继承 , 代码重用

3,多态性 一个父类多个子类 , 代码扩充性强


2.1 封装性

2.1.1 什么是封装?

将类中的成员(属性,方法,构造方法)信息隐藏,信息私有化,类之外的所有地方都不能访问。

2.1.2 作用?

1.保证数据的安全性

2.保证数据不被非法使用

2.1.3 如何实现封装?

1.需要封装的成员权限改为 private

控制权限: (限制成员的使用范围)

public 公开的 整个项目都可以使用

private 私有的 当前类

注意:企业开发中,为了保证数据安全,会将所有的属性都私有化。

  1. 封装的属性需要提供一组方法 setXX() 设置属性的值 getXX() 获得属性的值
 public class Emp {   //私有化属性   private int eno;   private String ename;   private double sal;      //构造方法   public Emp() {     }   public Emp(int eno, String ename, double sal) {   super();   this.eno = eno;   this.ename = ename;   this.sal = sal;   }  ​   /   * 获得eno的值   */   public int getEno() {   //可以添加判断   return eno;   }     /   * 获得薪资的方法   */   public double getSal() {   return sal;   }     /   * 设置薪资的方法   */   public void setSal(double sal) {   if(sal < 0) {   System.out.println("薪资不合法");   }else {   this.sal = sal;   }   }  }

测试类:

讯享网 public class TestEmp {   public static void main(String[] args) {   Emp p = new Emp(1,"jack",4000);          //获取员工编号   System.out.println(p.getEno());   //设置薪资   p.setSal(-9);   //获取薪资   //System.out.println(p.getSal());   }  }

注意:

setXX() xx属性名 必须有参数

getXX() xx属性名 必须有返回值

2.1.4 封装后会怎样?

1.属性赋值的整个过程:

  1. 默认值
  2. 声明的值
  3. 构造方法(对象创建时第一次值)
  4. setXX() (为了修改对象的属性值)

2.方法的封装(构造方法的封装)

封装方法: 当类中某些方法不希望外部类调用,仅限于类内部使用。

封装构造方法: 类不希望被创建对象(单例模式)

 public void open() {   //内部调取零件   startFixes();   System.out.println("电视打开");   }  //封装方法  private void startFixes() {   System.out.println("....零件1");   System.out.println("....零件2");   System.out.println("....零件3");   }

讯享网 public class Math{   //封装构造方法   private Math(){     }  }  ​

单例模式:

 public class Earth {   private static Earth earth = new Earth();     private Earth() {     }     public static Earth getEarth() {   return earth;   }  }

2.1.5 一个JAVA源文件的构成 Animal.java

包的声明(1次)
导包声明(n次)
类的声明(n个): 属性,方法,构造方法

讯享网 package  包;  import 包;  public  class  类名{      ​  //属性          ​  //方法    ​  //构造  ​  }  ​  class  类名{      ​  //属性          ​  //方法    ​  //构造  ​  }

包:

在JAVA中相当于文件夹。

作用:

  1. 将逻辑相关的类存放在一起
  2. 限制类的访问

包声明:

 package  根包.子包.子包;  package com.qf.oop;

注意:

1.包名全部小写

2.包之间用.间隔, 命名 : 网站后缀.公司名.项目名 网站后缀.公司名.项目名.emp

3.包声明一定在源文件的首行有效代码

导入包声明:

讯享网 import  根包.子包.*; //导入该包中所有资源  import  java.util.Arrays;  //导入JAVA中定义的类  import com.qf.homework.Student; //导入自定义的跨包类

注意:可以导入多个类

JAVA中提供包(API)

java.lang 核心包 System ,String ,Math....

java.util 工具包 集合,日期, Arrays ,Scanner

java.io 文件包 读写文件

java.net 网络

java.awt 图形窗口

注意:只有java.lang不需要手动导入 ;快捷键: ctrl + shift + o

2.2 继承性

2.2.1 类和类之间的关系

1.关联(包含) ”有“ has a

2.继承(泛化) ”是“ is a

3.依赖 ”用“ use a

1.关联(包含关系) A类中包含B类类型的属性 : 1对1 1对多(对象数组,集合) 多对多

 class  A{   //一对多   private B[] b;         //一对一      private  C c;  }  ​  class B{  ​  ​  }  class C{  ​  }

例如: 订单类 : 一个账户类 ,n个商品类

2.继承 A类满足B类,A类继承B的代码

讯享网 public class A extends B{  ​  ​  }

例如: 猫类继承动物类

3.依赖 A类的某个行为依赖于B类实现

 public class  Student{  ​   public void goToSchool(Bike b){               }      public void goToSchool(Car c){               }      public void goToSchool(Bus b){               }      // ..  ​  }

关联关系: A类包含B类,B类作为A类的属性

例子: 动物园 老虎 ; 餐馆 菜品 ; 运动会 体育项目 ; 美女类 衣服类

图书馆,书籍类 ; 美团 商铺 ; 超市 商品....

银行客户 账户;

 

用户类:

讯享网 package com.qf.oop.bank;  ​  public class User {   private String name;   private String card;   private String tel;   //包含   private Account acc;   public String getName() {   return name;   }   public void setName(String name) {   this.name = name;   }   public String getCard() {   return card;   }   public void setCard(String card) {   this.card = card;   }   public String getTel() {   return tel;   }   public void setTel(String tel) {   this.tel = tel;   }   public Account getAcc() {   return acc;   }   public void setAcc(Account acc) {   this.acc = acc;   }   @Override   public String toString() {   return "user [name=" + name + ", card=" + card + ", tel=" + tel + ", acc=" + acc + "]";   }   public User(String name, String card, String tel) {   super();   this.name = name;   this.card = card;   this.tel = tel;   }     public User() {     }    }  ​

账户类:

 package com.qf.oop.bank;  ​  public class Account {     private int accNo;   private String pass;   private double balance;   public Account(int accNo, String pass, double balance) {   super();   this.accNo = accNo;   this.pass = pass;   this.balance = balance;   }   public Account() {     }   public int getAccNo() {   return accNo;   }   public void setAccNo(int accNo) {   this.accNo = accNo;   }   public String getPass() {   return pass;   }   public void setPass(String pass) {   this.pass = pass;   }   public double getBalance() {   return balance;   }     @Override   public String toString() {   return "Account [accNo=" + accNo + ", pass=" + pass + ", balance=" + balance + "]";   }     /   * 存钱   */   public boolean deposit(double mon) {   if(mon > 0 && mon % 100 == 0) {   balance += mon;   return true;   }else {   return false;   }     }   /   * 取钱   */   public boolean withdraw(double mon) {   if(mon <= balance) {   balance -= mon;   return true;   }else {   return false;   }   }  }  ​

银行类:

讯享网 package com.qf.homework;  ​  import java.util.Scanner;  ​  public class Banking {   public static void main(String[] args) {   int[] acc = { 1001, 1002 };   String[] pass = { "", "" };   double[] balance = { 5000, 1000 };   Scanner sc = new Scanner(System.in);   while (true) {   System.out.println("欢迎使用ATM系统:1.登录 2.退出系统");   System.out.println("请输入操作编号:");   int opp = sc.nextInt();   if(opp == 1) {   System.out.println("请输入您的账户名:");   int no = sc.nextInt();   // 查找账户   int index = -1;   for (int i = 0; i < acc.length; i++) {   if (acc[i] == no) {   index = i;   break;   }   }   if (index != -1) {   System.out.println("请输入您的密码:");   String password = sc.next();   if (pass[index].equals(password)) {   // 密码正确   System.out.println("登录成功");   while (true) {   System.out.println("1.存钱");   System.out.println("2.取钱");   System.out.println("3.查看余额");   System.out.println("4.转账");   System.out.println("5.退出");  ​   System.out.println("请输入操作编号");   int opr = sc.nextInt();   if (opr == 1) {   System.out.println("请输入存款金额");   // 整百> 0   double money = sc.nextDouble();   if (money % 100 == 0 && money > 0) {   balance[index] += money;   } else {   System.out.println("金额有误");   }   } else if (opr == 2) {   System.out.println("请输入取款金额");   // 判断   double money = sc.nextDouble();   if (money > 0 && money <= balance[index]) {   balance[index] -= money;   } else {   System.out.println("余额不足");   }   } else if (opr == 3) {   System.out.println("当前余额:" + balance[index]);   } else if (opr == 4) {   System.out.println("请输入转账账户");   int no2 = sc.nextInt();   int index2 = -1;   for (int i = 0; i < acc.length; i++) {   if (acc[i] == no2) {   index2 = i;   break;   }   }   if (index2 != -1) {   System.out.println("请输入转账金额");   double m = sc.nextDouble();   if (m <= balance[index]) {   // index2 账户+   balance[index2] += m;  ​   // index -   balance[index] -= m;   System.out.println("转账成功");   } else {   System.out.println("金额不足");   }  ​   } else {   System.out.println("无此账户,无法转账");   }   } else if (opr == 5) {   break;   } else {   System.out.println("操作错误");   }   }   } else {   System.out.println("密码错误");   }   } else {   System.out.println("无此账户");   }   }   else if(opp == 2){   System.exit(0);   }else {   System.out.println("操作错误");   }   }   }  }  ​

测试类:

 package com.qf.oop.bank;  ​  public class TestBank {   public static void main(String[] args) {   new Bank();   }  }  ​

2.2.2 什么是继承?

利用现有的类构建新的类的过程,代码的继承。

现有的类 : 父类 , 根类 , 超类 , 基类

构建新类 : 子类 , 派生类 , 衍生类

“是” , is a 如 : 老虎类 动物类 (子类 满足父类特性,子类相对具体,父类相对抽象); 鞋子类 服装类 ; 小学生类 学生类

2.2.3 继承的作用?

代码重用,避免代码冗余

2.2.4 如何实现继承?

讯享网 控制权限   class  子类  extends  父类{  ​    }

注意:

控制权限: public 或者 不加权限default

子类继承时的父类只能一个

父类:

 public class Emp extends Object{   private int eNo;   private String eName;   private double eSal;       public int geteNo() {   return eNo;   }   public void seteNo(int eNo) {   this.eNo = eNo;   }   public String geteName() {   return eName;   }   public void seteName(String eName) {   this.eName = eName;   }   public double geteSal() {   return eSal;   }   public void seteSal(double eSal) {   this.eSal = eSal;   }   public Emp(int eNo, String eName, double eSal) {   super();   this.eNo = eNo;   this.eName = eName;   this.eSal = eSal;   }     public Emp() {     }       @Override   public String toString() {   return "Emp [eNo=" + eNo + ", eName=" + eName + ", eSal=" + eSal + "]";   }  }

子类:

讯享网 public class Manager extends Emp{   //奖金   private double bonus;  ​   public double getBonus() {   return bonus;   }  ​   public void setBonus(double bonus) {   this.bonus = bonus;   }  ​   @Override   public String toString() {   //super.toString() 父类的   return super.toString() + "Manager [bonus=" + bonus + "]";   }  }

测试类:

  Manager m = new Manager();   m.seteNo(2);   m.seteName("rose");   m.seteSal(6000);   m.setBonus(30000);   System.out.println(m);

2.2.5 可以继承哪些?

可以继承: 非私有的属性和方法

不可以: 私有的,构造方法不可以继承的

因此: 子类中: 父类的成员 + 子类自己成员

2.2.6 继承后的问题

1.JAVA中的继承关系? 类和类之间只存在单继承(一个父类可以有多个子类,每个子类只能一个父类)

2.JAVA中继承关系时多层的,越是上层级越抽象,越是下层级越具体

 

  1. Object是所有类的祖先类,顶级的,所有的类都直接或间接继承该类。
  2. JAVA中的权限(重点)

public protected 缺省 private
含义 公开的 受保护的 友好的,默认的 私有的
范围 整个项目 同包访问,跨包继承 同包访问 当前类

 

范围排序: public > protected > 默认 > private

讯享网 public class A {   public int a = 10;   protected int b = 20;   int c = 30;   private int d = 40;    }

使用:

类,接口 : public ,缺省

属性: 四个

方法,构造 : 四个

局部变量 : 没有权限

2.2.7 方法的重载和重写(覆盖)

当多个方法具有相同方法名,如果希望共存,就需要重载或重写。

 方法的重载:(方法的多样化) overload  ​  原则:  ​  1.方法名相同  ​  2.参数必须不同(个数,顺序,类型)  ​  3.权限和返回值不影响

讯享网 方法的重写:(方法的覆盖,子类将父类继承的方法加以改造)   override  ​  原则:  ​  1.方法名相同  ​  2.参数必须相同  ​  3.返回值必须相同  ​  4.权限不能降低   public > protected > 默认 > private

 package com.qf.oop;  ​  public class Father {   /   * 重载   * @param t   */   public void eat() {     System.out.println("爸爸吃肉");   }   public void eat(String t) {   System.out.println();   }   public int eat(String t,double k) {   return 0;   }  }  ​  class Son extends Father{   /   * 重写   */   public void eat() {   System.out.println("孩子喝奶");   }  }  public class TestFather {   public static void main(String[] args) {   Father f = new Father();          //爸爸吃肉   f.eat();     Son s = new Son();   //调用重写之后的方法          //孩子喝奶   s.eat();   s.eat("哇哈哈");   }  }

总结重载和重写的区别:

重载 重写(覆盖)
overload override
目的 方法多样化 子类覆盖父类
参数 参数必须不同 参数必须相同
权限 不限制 子类不能降低权限
返回值 不限制 必须相同
位置 本类,父子类 父子类
次数 n次 1次
异常 不限制 子类不能抛出更多异常

2.2.8 继承中的构造方法(难点)

  1. 子类不能继承父类的构造方法
  2. 子类需要手动调用父类的构造方法的:
讯享网 public 子类(类型  形参变量 ){      //父类继承的属性      super(实参1,实参2);      //自己定义的属性      this.xx = xx;  }

子类手动调用父类的构造方法:

 public Manager(int eNo, String eName, double eSal,double bonus) {   //调用父类   super(eNo,eName,eSal);   //自己   this.bonus = bonus;   }  //调用  public Emp(int eNo, String eName, double eSal) {   super();   this.eNo = eNo;   this.eName = eName;   this.eSal = eSal;   }  ​  //实例化:    public class TestEmp {   public static void main(String[] args) {   //Emp e = new Emp(1, "jack", 4000);     //System.out.println(e);   Manager m = new Manager(2, "rose", 6000, 30000);  // m.seteNo(2);  // m.seteName("rose");  // m.seteSal(6000);  // m.setBonus(30000);   System.out.println(m);   }  } 
讯享网 3. 继承中,构造方法执行顺序: 祖先 > 父类 > 子类  4. 当构造方法的第一行没有super(参数) ,系统默认提供super(); 自动调用父类的默认构造,因此,保证空构造
 public class GrandPa {     public GrandPa() {   super();   System.out.println("爷爷来啦");   }  }  ​  public class Father extends GrandPa{   public String name;     public Father(String name) {   //super()   System.out.println("爸爸来啦");   }    // public Father() {  //  // }  }  ​  public class Son extends Father{     public Son(String name) {   //super()   super(name);   System.out.println("孩子也来啦");   }    }  ​  public class TestSon {   public static void main(String[] args) {   Son son = new Son("jack");     }  }

2.2.9 总结super和this的使用

super的用法:

  1. 在子类中调用父类的被覆盖的属性和方法
讯享网 public class Student extends Person{   public String name = "小王";  ​   @Override   public String toString() {   return "父亲:" + super.name + ";孩子:" + this.name;   }  }

 public class Student extends Person{   public String toy;  ​   @Override   public String toString() {   return super.toString() + "toy=" + toy;   }  }

2.调用父类的构造方法

讯享网  public Person(String name) {   this.name = name;   }   public Person() {   //super(); //默认的   }

  public Student() {   //super();//父类的空构造   }   public Student(String name) {   super(name); // 手动调用   }

注意: super() 调用构造方法,一定放在构造方法的首行。

this的用法:(当前对象,对象本身)

  1. 调用本类的属性和方法(尤其全局变量被局部变量覆盖)
讯享网 public void setToy(String toy) {   this.toy = toy;   }

2. 调用本类的构造方法

  public Emp(int empno, String ename, double sal, int deptno) {   this(empno,deptno); //调用下面的构造方法   this.ename = ename;   this.sal = sal;     }     public Emp(int empno, int deptno) {   super();   this.empno = empno;   this.deptno = deptno;   }

注意:this() 调用构造方法,一定放在构造方法的首行。

2.3 多态性

2.3.1 什么是多态?

一个父类呈现出了多个子类形态,同一个动作展现出不一样的行为。

真正意义上的多态:

讯享网 父类  多态对象  =  new  子类(); // 向上转型

父类: Animal

子类: Tiger Rabbit Cat Dog Pig ....

 Animal a = new Animal()  Tiger t = new Tiger();  Cat c = new Cat();  Dog d = new Dog();

灵活的多态:

讯享网 Animal a  =  new  Dog();

生活中多态例子: USB : 风扇 , 键盘,鼠标,加湿器

 USB  b = new Mouse();  USB  b = new  KeyBoard();

2.3.2 多态的好处?

使得代码更加灵活,扩展性强

2.3.3 深入分析多态

讯享网 Animal a  =  new  Dog();

角度1:类型转换(编译角度)

当有继承关系:

 父类  对象名  = new  子类();  // 自动转换   向上转型  子类  对象名  = (子类)new  父类();  // 强制转换 向下转型

角度2: 多态底层的运行

 

2.3.4 多态对象的访问

只能访问父类的成员,当且仅当子类覆盖父类方法,执行子类的方法。

2.3.5 多态设计的必要条件

讯享网 1.继承,一个父类有多个子类  2.子类必须覆盖父类的方法  3.对象向上转型

父类:

 public class USB {   private String name;   public USB() {     }   public USB(String name) {   super();   this.name = name;   }   public String getName() {   return name;   }   public void setName(String name) {   this.name = name;   }   public void use() {   System.out.println("usb工作....");   }  }

子类:

讯享网 public class Mouse extends USB{  ​   @Override   public void use() {   System.out.println(getName() + "usb鼠标工作....");   }  ​   public Mouse() {   super();   // TODO Auto-generated constructor stub   }  ​   public Mouse(String name) {   super(name);   // TODO Auto-generated constructor stub   }  }  ​  public class KeyBoard extends USB{  ​   @Override   public void use() {   System.out.println(getName() + "usb键盘工作....");   }  ​   public KeyBoard() {   super();   // TODO Auto-generated constructor stub   }  ​   public KeyBoard(String name) {   super(name);   // TODO Auto-generated constructor stub   }  }

测试类:

 public class TestUSB {   public static void main(String[] args) {   //USB u = new Mouse("罗技");   USB u = new KeyBoard("樱桃");   u.use();   }  }

2.3.6 多态的实际应用

依赖关系的传参

讯享网 public class Developer {   /   * 依赖关系   * @param u   */   public void useTool(USB u) {   //调用覆盖的方法   u.use();   }  }

开发人员测试工具:

 public class TestUSB {   public static void main(String[] args) {   Developer d = new Developer();   d.useTool(new KeyBoard("樱桃"));//USB u = new KeyBoard("樱桃");   }  }

注意: 构造方法不能重写,可以重载

2.3.7 instanceof 向下转型

用于判断某个对象具体是哪一种类型的:(看new)

讯享网 对象   instanceof   类型(类/接口)

1.返回的是布尔类型: true(对象就是类型;对象是类型的子类类型) ; false(不是这个类型的)

2.如果对象和类型没有任何联系,出现编译错误

  Cat c = new Cat();   Animal a = new Animal();   Animal a2 = new Tiger();//向上转型 多态对象  ​  ​   System.out.println(c instanceof Cat); // true 对象就是猫类型   System.out.println(c instanceof Animal); // true 对象就是猫类型 是Animal子类   System.out.println(a instanceof Animal);     //System.out.println(c instanceof Student);   //System.out.println(c instanceof Tiger);// Tiger Cat没有联系,没有兄弟关系     System.out.println(a instanceof Cat); // false 动物对象不一定是猫     System.out.println(a instanceof Object);//true   System.out.println(c instanceof Object);//true     System.out.println(a2 instanceof Cat);//判断是否是猫

目的是多态对象向下转型,获取子类中的资源:

讯享网 Animal a = new Cat();  a.eat();  if(a instanceof Tiger) {   Tiger t = (Tiger)a;//向下转型   t.ao();  }

第三章 面向对象高级特性

3.1 abstract

3.1.1 什么是abstract?

抽象的,难以描述清楚,比较笼统。概念模糊。

3.1.2 abstract可以修饰哪些?

1.类 抽象类(抽象父类)

 public abstract class 类名{        }

2.方法 抽象方法

讯享网 控制权限   abstract  返回类型  方法名(形参类型 变量 ,形参类型 变量2 ) ;

3.1.3 抽象类的特征

1.抽象类一般作为父类,抽象类不能实例化

2.抽象父类强制要求必须有子类继承,子类将其描述清楚(必须有子类继承)

3.子类继承抽象父类之后,必须重写里面所有的抽象方法*,否则该类就成为抽象类*

4.抽象类中不一定都是抽象方法,可以有非抽象的; 有抽象方法的类必须是抽象类

5.抽象类是否包含构造方法?

抽象父类:

 public abstract class Fly {   private String name;   /   * 抽象方法   */   public abstract void fly();    // public abstract void hua();     /   * 非抽象   * @return   */   public String getName() {   return name;   }  }

子类继承和覆盖:

讯享网 public class Bird extends Fly{   @Override   public void fly() {   System.out.println("鸟飞行");     }  }  ​  public class Plane extends Fly {   @Override   public void fly() {   System.out.println("飞机飞行");  ​   }  }

测试类:

public class TestFly { public static void main(String[] args) { //抽象类不能实例化对象 //Fly f = new Fly(); //向上转型 Fly f = new Plane(); f.fly(); } }

注意:抽象父类有构造方法,给子类调用的。

3.1.4 抽象方法的特征

1.无法描述的行为,一定不能有方法体,不能加{ }

2.包含抽象方法的类一定是抽象类

讯享网public abstract void fly();

3.2 static

3.2.1 什么是static?

静态的,属于类的,不再属于某一个对象。

3.2.2 static可以修饰什么?

属性,方法,内部类

public class Test { //静态属性,类属性 private static int a ; / * 静态方法,类方法 * @param args */ public static void test() { //局部变量不能static int b = 10; } }

3.2.3 静态属性?

加static的属性: 静态属性,类属性,是所有对象共享的资源,不再单独属于某个对象。例如: 共享汽车 私家车 ;网吧电脑,自己电脑;

不加的属性 : 实例属性, 是每个对象独有的资源。

人: 姓名 年龄 科目(灵长目类), 肤色

讯享网 public class Person {   //实例属性   private String name;   private int age;   //静态属性   private static String type = "灵长目";    }

检测静态属性的特点:

 package com.qf.oop;  ​  public class TestStatic {   public int i = 10;   public static int j = 20;     public TestStatic() {   i ++;   j ++;   }     public static void main(String[] args) {   TestStatic t1 = new TestStatic();   System.out.println(t1.i + "," + t1.j);// 11 21     TestStatic t2 = new TestStatic();   System.out.println(t2.i + "," + t2.j);// 11 22     }  }

堆栈图:

 

静态属性和实例属性的区别:(记住)

静态属性 实例属性
含义 属于类的,对象共享资源 每个对象独有
个数 一个类一份拷贝 n份
内存分配 静态区
初始化时机 类加载的时候(类使用之前) 创建对象
调用 类.静态属性 / 对象.静态属性 对象.实例属性

调用:

讯享网public class TestStatic { public int i = 10; //实例属性 public static int j = 20; //静态属性 public TestStatic() { i ++; j ++; } public static void main(String[] args) { TestStatic t = new TestStatic(); // B 错误 其余都对 // A t.i // B TestStatic.i // C TestStatic.j // D t.j } }

3.2.4 静态方法?

  1. 静态方法只能调用静态的属性和方法,不可以调用非静态属性和方法
  2. 实例方法可以调用静态的方法
  3. 当静态方法就是要调用非静态: 只能创建对象
  4. 类名.静态方法()推荐的 / 对象.静态方法() 可以的
package com.qf.oop; / * 测试静态方法的调用 * @author 86136 * */ public class Test2 { int a = 10; static int b = 10; public static void main(String[] args) { System.out.println(Math.random()); t1(); //非静态方法先创建对象才使用 Test2 ttt = new Test2(); ttt.t3(); } //静态方法 public static void t1() { System.out.println(b); Test2 ttt = new Test2(); System.out.println(ttt.a); t2(); //t3(); } public static void t2() { } //实例方法 public void t3() { System.out.println(a); System.out.println(b); t1(); t2(); } }

3.2.4 静态代码块?

静态代码块用于初始化静态的成员。

讯享网//静态代码块 static{ // 初始化静态属性 } //实例代码块 { }

1.位置 和构造方法同级

2.个数 可以有多个,按照顺序执行

3.时机 类加载时

4.次数 1次

5.顺序 静态 1> 实例 n > 构造 n

public class Test3 { public static int a ; public int b; static { //a = 20; System.out.println("静态代码块"); } // static { // a = 30; // } { System.out.println("实例代码块"); } public Test3(int b) { System.out.println("构造方法"); this.b = b; } }

3.3 final

3.3.1 什么是final?

最终的,最后的。

3.3.2 final修饰什么?

变量(属性+局部变量) 常量

方法

讯享网public final class TestFinal { public final String TEACHER = "Miss Yu"; public final void test() { final int YEAR = 365; } }

3.3.3 final修饰内容的特点?

  1. final修饰的变量: 常量,一经定义不能改 ; final修饰的属性必须设置初始值,不可以使用默认值
  2. final修饰的方法: 不能被重写
  3. final修饰的类 : 不能有子类(最后的类)

JAVA中哪些类final修饰类: Math ,String,Integer

3.4 修饰符共用

abstract: 类 方法

static : 属性 方法

final: 变量 方法 类

1.不能混合使用

abstract和static

abstract和final

abstract 和 private

2.可以混用

static和final可以一起修饰属性和方法,不限制顺序

public class TestFinal2 { public final static int AGE = 20; public static final double PI = 3.; public static void main(String[] args) { System.out.println(TestFinal2.AGE); System.out.println(TestFinal2.PI); } public static final void test() { } }

第四章 接口

4.1 接口的意义

当一个子类继承了父类之后,不能具备其他父类的特性,接口可以使得类具备多种特性。

目的是解决单继承问题。

接口作为引用数据类型,抽象概念,只定义方法声明。 what is ?(定义是什么) How is ?(怎么样不管)

注意:开发中,设计和实现是分离的,接口是设计层面,架构师设计有什么; 类是实现层面,将接口中定义的内容具体实现

4.2 接口的定义

讯享网控制权限 interface 接口名{ }

注意:

1.控制权限 public 缺省

2.关键字 interface

3.接口名 : 同类名 , IWeapon , IVehicles

4.3 接口的实现

控制权限 class 实现类 extends 父类 implements 接口1,接口2...{ }

注意:

实现类可以同时实现多个接口,具备多种特性

继承只能一个父类 ,实现多个接口 (单继承,多实现)

案例:

讯享网 //武器接口  public interface IWeapon {  ​  }  //交通工具接口  public interface IVehicles {  ​  }  //钢铁父类  public abstract class Iron {  ​  }  //实现类  public class Tank extends Iron implements IWeapon,IVehicles{  ​  }  //抽象类实现  public abstract class UFO implements IWeapon, IVehicles{  ​  }

注意: XXXImpl

4.4 接口中的成员

 属性: 公开的静态常量   public static final = 初始值;  方法: 公开的抽象方法   public abstract 返回值 方法名(参数) ;

注意:

  1. 接口中属性和方法的修饰符全是默认的定死的,即使省略,必须是该类型
  2. 接口中没有构造方法,肯定不能实例化

讯享网public interface IWeapon { //静态常量 public static final int POWER = 100; int DEFENCE = 50; //抽象方法 public abstract void fire() ; String fix(int hour); }

4.5 实现类的实现

1.覆盖接口中所有的抽象方法

public class Gun implements IWeapon{ @Override public void fire() { System.out.println("开炮"); } @Override public String fix(int hour) { System.out.println("保养" + hour + "小时"); return "恢复,准备就绪"; } } 

2.接口中的常量

接口名.属性,直接使用,不能修改

3.接口中多态

讯享网接口类型 多态对象 = new 实现类();

public interface Photograph { void shot(); } class Camera implements Photograph{ @Override public void shot() { System.out.println("相机拍照"); } } class Phone implements Photograph{ @Override public void shot() { System.out.println("手机拍照"); } }

讯享网public class Photographer { private static final String NAME = "义民"; / * 使用设备拍照 */ public void takePhoto(Photograph p) { System.out.println(NAME + "拍照:"); p.shot(); } / * 测试 */ public static void main(String[] args) { new Photographer().takePhoto(new Camera()); } }

4.6 类和接口的关系

关系 继承角度 关键字
类和类 单继承 一个父类多个子类,每个子类一个父类 extends public class 子类 extends 父类{}
类和接口 多实现 接口多个实现类,每个实现类实现多个接口 implements public class 实现类 implements 接口1,接口2...{}
接口和接口 多继承 父接口可以有多个子接口,每个子接口继承多个父接口 extends public interface 子接口 extends 父接口1,父接口2...{}

public interface A extends B,C{ } interface B { } interface C { }

4.7 抽象类和接口的区别(重点)

抽象类 接口
定义 abstract class interface
属性 自定义 private public static final
方法 自定义 (抽象+非抽象) public abstract
构造方法
与类关系 单继承 多实现

相似点: 1. 都有抽象的方法存在 2.都不能实例化对象,都不能new

特例: jdk8+

讯享网public interface More { public abstract void test(); / * jdk8+ 非抽象方法 */ public default void test2() { } }

第五章 枚举

5.1 枚举的意义

枚举表示一一列举,用于一组固定的离散值,比如:性别固定 男,女 ; 月份 1-12 ; 四季 , 星期, 十二生肖 , 四大名著,人民币面值(100,50,20,10,5,1), 交通灯(红色,绿色,黄色),26字母。

5.2 枚举的作用

  1. 代码的安全更高, 不会非法调用
  2. 降低代码的耦合度
  3. 代码的可读性增强,不会使用int,String代表其含义

5.3 枚举的声明

控制权限 enum 枚举名{ }

注意:

控制权限 : public 缺省

枚举名 : 首字母大写,合法标识符

5.4 枚举中的成员

讯享网控制权限 enum 枚举名{ 枚举常量 , 枚举常量2 ; }

5.5 枚举中的成员调用

枚举名.枚举常量

讯享网 public enum Light {   RED,GREEN,YELLOW;  }  public class TestLight {   public static void main(String[] args) {   System.out.println(Light.RED);   }  }

在switch中使用枚举:

 /   * 交通   * @author 86136   *   */  public class Traffic {   //定义属性,切换完信号灯的颜色   private Light curr ;  ​   public Light getCurr() {   return curr;   }   public void setCurr(Light curr) {   this.curr = curr;   }   /   * 信号切换   */   public Light change(Light l) {   switch (l) {   case RED:   curr = Light.GREEN;   break;   case YELLOW:   curr = Light.RED;   break;   case GREEN:   curr = Light.YELLOW;   break;   }     return curr;   }  }  /*测试*/  public class TestTraffic {   public static void main(String[] args) {   Traffic t = new Traffic();   //切换   System.out.println(t.change(Light.RED));   }  }

5.6 工厂模型

23种设计模式: 单例模式,静态工厂模式,代理模式,生产者消费者....

单例模式: 获得对象实例只有一个

讯享网 public class  Singleton{   private static Singleton ins = new Singleton();        /      使用方法返回一个实例*/            public static Singleton getSingleton(){                    return ins;     }    }

案例:

 public class Earth {   private static Earth ins = new Earth();     private Earth() {     }        /使用方法返回一个实例*/            public static Earth getEarth(){                    return ins;     }  }  ​  public class TestEarth {   public static void main(String[] args) {   Earth e1 = Earth.getEarth();   Earth e2 = Earth.getEarth();     System.out.println(e1 == e2);//单实例   }  }

静态工厂模式: 根据类型需要,生产对象。

讯享网 public interface IShoe {     public abstract void info();  }  public enum ShoesType {   ADIDAS,NIKE,ANTA;  }  public class Nike implements IShoe{  ​   @Override   public void info() {   System.out.println("耐克鞋轻巧好穿");   }  ​  }  public class Adidas implements IShoe{  ​   @Override   public void info() {   System.out.println("阿迪好看,抗造");   }  ​  }  public class Anta implements IShoe{  ​   @Override   public void info() {   System.out.println("安踏永不止步");   }  ​  }  /   * 静态工厂   * @author 86136   *   */  public class ShoesFactory {     private static IShoe shoe;  ​   /   * 多态属性   * @param type   * @return   */   public static  IShoe  make (ShoesType type) {   switch (type) {   case ADIDAS:   shoe = new Adidas();   break;  ​   case NIKE:   shoe = new Nike();   break;     case ANTA:   shoe = new Anta();   break;   }     return shoe;   }    }  public class TestFactory {   public static void main(String[] args) {   //多态   IShoe shoe = ShoesFactory.make(ShoesType.NIKE);   shoe.info();   }  }

第六章 内部类

6.1 什么是内部类?

定义在类里的类,称之为内部类,外部的叫做外部类。

6.2 内部类的分类

① 静态内部类

② 实例内部类

③ 局部内部类

 public class Outer {   /   * 静态内部类   *   */   public static class Inner{   public int a  = 10;   public static int b = 20;   }   /   * 实例内部类   *   */   public class Inner2{   public int a = 30;   }     public void test() {   //局部内部类   class Inner3{     }   }  }

静态内部类:

讯享网外部类.静态内部类

public class TestInner1 { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); System.out.println(inner.a); System.out.println(Outer.Inner.b); } }

实例内部类:

讯享网new 外部类().new 实例内部类();

public class TestInner2 { public static void main(String[] args) { Outer.Inner2 inner2 = new Outer().new Inner2(); System.out.println(inner2.a); } }

局部内部类:看方法,外部类调用方法

讯享网public void test() { //局部内部类 class Inner3{ int a = 50; public void test2() { System.out.println("局部内部类"); } } Inner3 inner3 = new Inner3(); System.out.println(inner3.a); inner3.test2(); } public class TestInner3 { public static void main(String[] args) { Outer outer = new Outer(); outer.test(); } } 

6.3 匿名内部类(重点)

① 该内部类没有名字

② 以上三种内部类都可以是匿名的,主要是局部内部类

抽象父类 变量名 = new 抽象父类(){ //抽象父类的子类的类体 } 接口 变量名 = new 接口(){ //实现类的类体 } 

讯享网public interface IAnimal { void eat(); }

  IAnimal animal = new IAnimal() {  ​   @Override   public void eat() {   System.out.println("小猫吃老鼠");   }     };     animal.eat();     //lambda JDK8+   IAnimal animal2 = () -> System.out.println("小鹿吃草");     animal2.eat();

小讯
上一篇 2025-03-22 09:51
下一篇 2025-01-09 07:39

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/65502.html