当前位置: 首页 > news >正文

学习笔记——《Java面向对象程序设计》-内部类、匿名类、异常类

参考教材:

Java面向对象程序设计(第3版)微课视频版 清华大学出版社

1、内部类

类中可以有两种重要的成员:成员变量和方法。实际上Java还允许类可以有一种成员:内部类。

内部类可以使用其外嵌类中的成员变量;内部类中的方法也可以调用外嵌类中的方法。

内部类的类体中不可以声明类变量和类方法。

外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。

内部类仅供它的外嵌类使用;

内部类的外嵌类的成员变量在内部类中有效,使得内部类和外嵌类的交互更加方便。

class RedCowFarm{static String farmName;RedCow cow;RedCowFarm(){	}RedCowFarm(String s){cow = new RedCow(150,112,5000);farmName = s;			}void showCowMess() {cow.speak();}class RedCow{String cowName = "红牛";int height,weight,price;RedCow(int h,int w,int p){height=h;weight=w;price=p;}void speak() {System.out.println("我是"+cowName+",身高:"+height+"cm,体重:"+weight+"kg,生活在"+farmName);}}}public class Example6_1 {public static void main(String[] args) {RedCowFarm farm = new RedCowFarm("红牛农场");farm.showCowMess();farm.cow.speak();}
}

内部类可以被修饰为static内部类,那么static内部类就是外部类中的一种静态数据类型,这样,程序就可以在其他类中使用static内部类来创建对象。

注意:static内部类不能操作外部类中的实例成员变量。

class RedCowFarm{static String farmName;RedCow cow;RedCowFarm(){	}RedCowFarm(String s){cow = new RedCow(150,112,5000);farmName = s;			}void showCowMess() {cow.speak();}static class RedCow{String cowName = "红牛";int height,weight,price;RedCow(int h,int w,int p){height=h;weight=w;price=p;}void speak() {System.out.println("我是"+cowName+",身高:"+height+"cm,体重:"+weight+"kg,生活在"+farmName);}}}public class Example6_1 {public static void main(String[] args) {RedCowFarm farm = new RedCowFarm("红牛农场");RedCowFarm.RedCow cow = new RedCowFarm.RedCow(180,119,6000);cow.speak();

2、匿名类

1、和子类有关的匿名类(匿名子类)

Java允许,直接使用一个类的子类的类体创建一个子类对象,即,创建子类对象时,除了使用父类的构造方法外,还有类体,此类体被认为是一个子类去掉声明后的类体。

假设Bank是类,则以下代码就是用Bank的一个子类(匿名类)创建对象。

//创建子类过程中,首先一定会调用父类的构造方法,因此需写明调用的哪个构造方法
new Bank(){//子类(匿名类)的类体
};
//原始写法
class A{void f() {System.out.println("I am A");}
}public class E {public static void main(String[] args) {A a = new A();//创建对象a.f();}
}

匿名类一定是内部类。

class A{void f() {System.out.println("I am A");}
}class B extends A{void f() {System.out.println("Hello");}
}public class E {public static void main(String[] args) {//用A的子类创建对象,此时a为子类(匿名类)对象的上转型对象//此时,a可以访问子类继承/重写的方法A a = new A(){void f() {System.out.println("你好");}};a.f();a = new B(); //子类创建对象,引用赋给父类对象a.f();}
}

2、和接口有关的匿名类

假设Computer是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computer接口的类去掉类声明后的类体,称作匿名类。

new Computer(){//实现接口的匿名类的类体
};
interface A{abstract void f();
}class B implements A{public void f() {System.out.println("Hello");}
}public class E {public static void main(String[] args) {//实现A接口的匿名类A a = new A(){public void f() {System.out.println("你好");}};a.f();a = new B(); //B实现接口a.f();}
}

3、Lambda表达式

Java中的Lambda表达式主要目的是在使用单接口(只含有一个方法的接口)匿名类时,让代码更加简洁。

Lambda表达式就是一个匿名方法(函数)

//通常写法
int f(int a,int b){return a+b;
}//Lambda表达式写法
(int a,int b)->{return a+b;
}

Lambda表达式过于简化,因此必须在特殊的上下文,编译器才能推断出到底是哪个方法,因此,Java中的Lambda表达式主要用在单接口(只含有一个方法)中。

interface Cubic{double getCubic(double x);
}public class aLambda {public static void main(String[] args) {	Cubic a = new Cubic() {public double getCubic(double x) {return x*x*x;}};System.out.println(a.getCubic(5));}
}
interface Cubic{double getCubic(double x);
}public class aLambda {public static void main(String[] args) {	Cubic a = (double x) ->{return x*x*x;};System.out.println(a.getCubic(5));}
}

3、异常类

所谓异常就是程序运行时可能出现一些错误,比如试图打开一个不存在的文件。

异常处理会改变程序的控制流程,让程序有机会对错误进行处理。

1、try~catch、finally语句

try{//包含可能发生异常的语句,即可能throw关键字抛出了异常对象(抛出Exception子类对象)
}
catch(ExceptionSubClass1 e){//...
}
catch(ExceptionSubClass2 e){//...
}

只要抛出异常,try语句就结束了,throw后面的语句无法执行;

import java.io.IOException;//IOException是一个类,可以用该类创建对象public class aException {public static void main(String[] args) {int x = 100;try {x = 999;//throw后必须跟异常类或其子类创建的对象,抛出对象引用throw(new IOException("读取文件错误"));// x = -999;//该语句无法执行}catch(IOException e) {x=-1000;System.out.println(e.getMessage());}System.out.println(x);}
}

Java的异常经常发生在方法调用过程中,即在方法调用过程中抛出异常对象,导致程序运行出现异常,并等待处理。

java.lang包中的Integer类调用其他类方法:public static int parseInt(String s)可以将“数字”格式的字符串,如“982”转换为数字,但当试图将字符串"ab85"转换成数字时,例如:int number = Integer.parseInt("ab85");方法parseInt在执行过程中就会抛出NumberFormatException对象(parseInt方法体中有代码使用关键字throw抛出一个NumberFormatException对象),即程序运行出现NumberFormatException异常。

public class Example26 {public static void main(String[] args) {//下面的代码定义了一个try…catch…finally语句用于捕获异常try {int result = divide(4, 0);       //调用divide()方法System.out.println(result);} catch (Exception e) {               //对捕获到的异常进行处理System.out.println("捕获的异常信息为:" + e.getMessage());return;                             //用于结束当前语句} finally {                             System.out.println("进入finally代码块");}System.out.println("程序继续向下执行…");}//下面的方法实现了两个整数相除public static int divide(int x, int y) {int result = x / y;           //定义一个变量result记录两个数相除的结果return result;                 //将结果返回}
}/*
运行结果:
捕获的异常信息为:/ by zero
进入finally代码块没有执行System.out.println("程序继续向下执行…");的原因:调用divide(4, 0)时,由于除数为0,会抛出ArithmeticException。
异常被捕获后,执行System.out.println("捕获的异常信息为:" + e.getMessage());return语句的作用:catch块中的return语句会立即结束当前方法(main方法)的执行。
*/

在实际开发中,大部分情况下我们会调用别人编写方法,并不知道别人编写的方法是否会发生异常。 针对这种情况,Java允许在方法的后面使用throws关键字对外声明该方法有可能发生的异常,这样调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过。

public class Example28 {public static void main(String[] args) {//定义try…catch语句用于捕获异常try {int result = divide(4, 2);   //调用divide()方法System.out.println(result); } catch (Exception e) {           //对捕获到的异常进行处理e.printStackTrace();          //打印捕获的异常信息}}//使用throws关键字声明抛出异常public static int divide(int x, int y) throws Exception {int result = x / y;      //定义一个变量result记录两个数相除的结果return result;            //将结果返回}
}

2、自定义异常类

可以拓展Exception类定义自己的异常类,然后规定哪些方法产生这样的异常。

class IntegerException extends Exception{String message;public IntegerException(int m) {message = "年龄"+m+"不合理";}public String toString() {return message;}
}public class People {private int age = 1;public void setAge(int age) throws IntegerException{if(age>=160 || age<=0) {//方法抛出异常,导致方法结束throw new IntegerException(age); }else {this.age=age;}}public int getAge() {System.out.println("年龄"+age+"合理");return age;}public static void main(String[] args) {	People wang = new People();	try {wang.setAge(180);System.out.println(wang.getAge());}catch(IntegerException e){System.out.println(e.toString());}}
}

相关文章:

  • rsync+ Rocky Linux 主机同步部署实战
  • 4月26日星期六今日早报简报微语报早读
  • 创建可执行 JAR 文件
  • 如何在 Conda 环境中降级 Python 版本:详细指南
  • MyBatis 插件开发的完整详细例子
  • 通过门店销售明细表用Python Pandas得到每月每个门店的销冠和按月的同比环比数据
  • Pygame字体与UI:打造游戏菜单和HUD界面
  • 《淘宝API数据治理实践:采集字段标准化与数据质量监控体系》
  • 6.1 客户服务:智能客服与自动化支持系统的构建
  • 获取房源信息并完成可视化——网络爬虫实战1
  • C++模拟Java C#的 finally
  • 揭开人工智能的神秘面纱:从概念到人工神经网络
  • springboot入门-JPA(Java Persistence API)注解与实体类Model
  • 线程池(二):深入剖析synchronized关键字的底层原理
  • 上位机知识篇---寻址方式
  • 电商秒杀系统技术栈与难点解析 - Java架构师面试实战
  • Unity网络编程入门:掌握Netcode for GameObjects实现多人游戏基础(Day 39)
  • Word/WPS 删除最后一页空白页,且保持前面布局样式不变
  • Cribl 上传lookup 表,传入数据进event
  • 【Java面试笔记:进阶】21.Java并发类库提供的线程池有哪几种? 分别有什么特点?
  • 图像编辑新增一款开源模型,阶跃星辰发布Step1X-Edit
  • 国家统计局:一季度规模以上工业企业利润延续持续恢复态势
  • 一图读懂|上海海关公布一季度数据:钢材出口增长超143%
  • 谷歌一季度利润增超四成:云业务利润率上升,宏观环境可能影响广告业务
  • 山东一季度GDP为23466亿元,同比增长6.0%
  • 城事|喊侬白相,长兴太湖9号公路邀上海市民共赴诗意之旅