java基础知识复习上篇

本教程全面介绍了Java编程语言,从环境搭建、语法基础到面向对象编程,深入浅出讲解Java核心技术,适合初学者快速掌握Java编程。

一.概述

(一)java简述

1.java语言是SUN公司在1995年推出的一门编程语言。
2.java的应用领域:

  • Java SE:Java标准版,提供了完整的java核心文档,用于开发客户端独立的应用程序。
  • Java EE:Java企业版,用于开发服务器端的应用程序。
  • Java ME:Java微型版,用来开发移动设备,比如手机,Pad等等。

3.java语言的特点:面向对象跨平台
4.java之父:James Gosling

(二)java开发环境

1.JDK:SUN公司提供了一套java开发环境,Java Development Kit , 简称JDK。它是整个java的核心,包含了java编译器(javac.exe)java运行工具(java.exe)java文档生成工具(javadoc.exe)、**java打包工具(jar.exe)**等等。
2.JDK的版本:在1995年,SUN公司推出的JDK最早版本1.0,随后相继推出很多的版本,其中JDK1.8有很多的改变,如果是维护老项目推荐下载JDK1.8前的版本。
3.JRE:SUN公司除了提供JDK,还提供了java运行环境,也就是Java Runtime Environment,简称就是JRE。JRE包含Java虚拟机(JVM)和Java程序所需的核心类库,JRE只包含Java运行工具,不包含编译工具。JDK包含了JRE工具,下载JDK即可,不用单独下载JRE。
4.环境变量的配置:

  • JAVA_HOME:安装JDK的路径
  • CLASSPATH: Java加载类的路径
  • PATH:添加%JAVA_HOME%\bin

5.运行步骤:

  • 打开cmd窗口
  • 在cmd窗口中执行javac 源文件名.java,此时会生成对应的字节码文件,以.class后缀结尾
  • 运行java 字节码文件(不能加后缀)

(三)java运行机制

1.java虚拟机:Java虚拟机(Java Virtal Machine),简称JVM,这是一个虚拟的计算机,负责执行指令,管理数据、内存、寄存器等等。
2.垃圾回收机制:Garbge Collection,简称GC,java提供了自动回收垃圾的机制,不用自己手动回收。
3.Java运行步骤:编译和运行,首先是将.java后缀的文件源文件进行编译,然后生成.class的字节码文件,最后java虚拟机将字节码文件进行解释执行,并且将结果显示出来。
HelloWorld实例具体步骤:

  • 1.编写HelloWorld.java的文件;
  • 2.javac HelloWorld.java,开启java编译器进行编译,编译结束后,生成HelloWorld.class字节码文件;
  • 3.java HelloWorld(注意,不能加.class后缀)启动java虚拟机运行程序,java虚拟机将编译后字节码文件加载到内存,这个过程叫做类加载,它是由于类加载器完成的,然后虚拟机针对内存中的Java类进行解释执行,就可以看到执行结果。

(四)开发工具

java最主要的开发工具就是IDEA和Eclipse。

二.变量、数据类型、运算符

(一).java语言的注释

  • 单行注释://,快捷键Ctrl+/
  • 多行注释:/**/,快捷键Ctrl+Shift+/,多行注释不能嵌套使用。
  • 文档注释:主要用于介绍代码的基本情况:比如编写代码的作者,代码的一些说明等等。

(二)变量

  • 局部变量:在方法或者语句块内部定义变量,声明周期是从声明位置到方法或者语句执行完毕为止。局部变量在使用前,必须先声明、初始化,才能使用。
  • 成员变量(实例变量):方法外部,类的内部定义的变量,从属于对象,生命周期伴随是对象始终,如果成员变量没有进行初始化,那么会根据变量的类型默认初始化。
  • 静态变量:关键static定义的变量,从属于类,生命周期伴随着类始终,从类的加载到卸载,如果不进行初始化,与成员变量相同,会根据变量的类型进行初始化。
public class Test {

static int staticSize = 5; //静态变量,从属于类Test
int size; //成员对象,从属于对象

public static void main(String[] args) {
Test test = new Test();
test.size = 2;
System.out.println("成员变量:" + size);
System.out.println("静态变量:" + Test.staticSize);
{
    int  i = 10;  //局部变量 只能在{}中使用
    System.out.println("局部变量:" + i );
}
}
}

变量命名和规范

  • 见名知意
  • 类成员变量,局部变量:首字母小写和驼峰原则 比如:manSalay。
  • 常量:大写字母和下划线 比如:PI。
  • 类名:首字母大写和驼峰原则: Man。
  • 方法名:首字母小写和驼峰原则: run(), runTime()。

(三)常量

常量的关键是final,常量命名规范是字母都是大写,但是要注意定义常量的时候必须要初始化,并且初始化后的值就不能发生改变。

(四)数据类型

数据类型的分类:基本数据类型和引用数据类型,其中引用数据类型的大小统一为4个字节,记录的是引用对象的地址。
1基本数据类型(9大类型)

  • 数值型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)、float(4字节)、double(8字节)
  • 字符型:char(2字节)
  • 布尔型:boolean(只占有1位)

基本数据类型——整型
整型有4种表现形式:十进制、八进制(以0开头)、十六进制(以0x/0X开头)、二进制(以0b/0B开头)。
注意:java常量默认为int类型,如果声明long变量没有超过int类型(大约21亿),则可以不需要再后面加上l或者L。

long a = 2000;
System.out.println(a); //编译成功
//long aa = 2222222222222222;超出了int类型的范围,编译出错
long aa = 2222222222222222L;//默认声明的类型是int,添加L则为long类型
//推荐使用大写的L,小写l容易1区分

基本数据类型——浮点型
浮点型有两种类型,一种是float单精度类型,占4个字节,尾数可以精确到7位有效数字。另一种是double双精度类型,占8个字节,浮点型普遍采用双精度。
浮点类型的表现方式:十进制和科学记数法

float f = 3.14f;
double d = 3.14E2;//科学记数法表示  E表示十次方
//浮点数误差问题
float fa1 = 0.1F;
float fa2 = 1.0/10;
System.out.println( fa1 == fa2 );//结果为false
//说明浮点数存在误差,数字不能精确表示

基本数据类型——字符型
字符型char占有两个字节,在java中使用单引号来表示字符常量。char表示的是Unicode编码表中的字符,Unicode编码被设计用来处理各种语言的文字,它占2个字节,可允许有65536个字符。

char ca = 'A';
char cb = '张';
char cc = '\u0066';  
System.out.println("" + ca + cb + cc); //输出前面加上""字符输出自动转换为字符串

基本数据类型——boolean
boolean类型是两个常量值:true和false,在内存中占有一位(注意不是一个字节),不可以使用0或者非0的整数代替true或者false。(与C语言不同)

(五)运算符

运算符:用于操作变量。

  • 算术运算符:+、-、*、/、%
    注意:取模运算余数的符号与左边的操作数相同,与右边的操作数无关。

  • 自增自减运算符:++、–,前置的自增自减是先加1/减1,然后赋值,后置的自增自减是先赋值后加1/减1。

  • 关系运算符:==,!=:针对所有的类型都可以使用,>,<,>=,<=:只针对数值类型

  • 逻辑运算符:与,或,非,短路与,短路或,注意:短路与和短路或如果左边的操作数结果就可以确定逻辑表达式的值,那么就不会再继续执行右边的操作数,有利于提高效率。
    -位运算:进行二进制的运算:取反、与、或、异或、左移<<(左移一位相当于乘以2)、右移>>(右移一位相当于除以2)。
    注意:&,|既可以是逻辑运算符,也可以是位运算符,如果两侧操作数都是boolean类型,就作为逻辑运算符。如果两侧的操作数是整数类型,就是位运算符。

  • 赋值运算符及其扩展运算::=,或者是算术运算符加上=,需要注意的是赋值运算符的扩展是把右边的结果运算给左边。

  • 条件运算符(三目运算符):x ? y : z,x是表达式,返回的是布尔值,y是结果的true的表达式,z是结果为false的表达式。

(六)数据类型转换

1.自动类型转换
自动类型转换就是指将容量小的数据类型转换为容量大的数据类型。(这里的容量不是指字节数)。

byte a = 13;
int b = a;//byte类型自动转换为容量更大的int类型
float f1 = 22.5F;
int f2 = f1;//出现错误,容量不是字节,int类型和float类型字节相同,但是float不会自动转换为int类型。

2.强制类型转换
强制类型转换有称为造型,用于显式转换一个数值的类型。使用强制类型转换会出现信息丢失的情况,会造成精度降低或者溢出。

double d = 3.99;
int i = (int)d;//结果为3,舍弃小数部分,注意不是四舍五入,而是将小数全部舍去。

三.选择语句、循环语句、跳转语句

(一)选择语句

选择语句:if、if else 、if…else if… else、switch。
选择语句使用的注意事项:

  • 如果if语句后面没有语句块{},那么if语句只会作用后面的第一条语句。
  • switch语句没有break,那么后面的语句还会继续执行。
//随机产生26个字母实例
char a = 'a';
int rand = (int)(26*Math.random());//随机产生25个数字
char word = (char)(rand + a);  //25个数字加上a的值,再转换为字符
System.out.println(word + ":");
switch(word) {
		case 'a':
	    case 'e':
	    case 'i':
	    case 'o':
	    case 'u':
	            System.out.println("元音");
	            break;
	    case 'y':
	    case 'w':
	            System.out.println("半元音");
	            break;
	    default:
	            System.out.println("辅音");
	        }

(二)循环语句

while do…while for,其中while和for叫做当型,do…while叫做直到型。

//打印九九乘法表
for(int n = 1; n <= 9; i++) { //控制行
   for(int m = 1; m <= n; m++) { //控制列
   int result = n * m;
   System.out.println(m + "*" + n + "=" + result + " ");
}
//每打印此就换行
System.out.println();
}

(三)跳转语句

跳转语句:break和continue。
break:强行退出循环,不执行循环剩下的语句,
continue:终止本次循环,跳过本次循环体内为执行的语句,进入下一次循环。
注意:continue用来while,do while中,continue语句立即跳到循环首部,越过当前循环的剩余部分,continue用于for循环则跳到迭代因子部分。

//计算100到300内可以被3整除的数,每5个数换一行
int count = 0;  //计数器
for(int i = 101; i < 301; i++) {
if(i % 3 == 0) {
   continue; //结束本次循环,不会执行本次循环后的语句
}
System.out.println(i + " ");
count ++;
if(count % 5 == 0) {
System.out.println();
}
}

四.方法

方法是用来完成特定功能的代码片段,也就是C语言的函数。

(一)形参与实参

  • 形参:方法声明时括号内定义的参数,用来接收外界传入的数据。
  • 实参:方法调用时候传入的参数,是实际的数据。

(二)返回值

返回值:方法执行完之后调用返回的数据。
返回值的类型:事先约定的数据类型,比如说int类型,double类型,如果无返回值,必须返回必须指定为void。
return的作用

  • 终止方法的运行
  • 指定返回数据

(三)值传递和引用传递

值传递:传递的是数据的副本,改变传递数据的值,不会改变原先的值,操作的实际上是数据copy的值。
引用传递:传递时该对象引用的copy值,但是指向的是同一个对象。
Java中进行方法调用中传递参数时,遵循值传递的原则(传递的都是数据的副本)。

(四)方法的重载

重载:一个类内定义的相同的方法名,但是形参的类型和个数不相同,这就叫做方法的重载。
方法重载的意义就在于,使用同一方法名的时候,写入实际的数据,系统可以根据数据的差别而去调用方法,关键就在于能让系统知道去调用哪一个方法。

public static int add(int a,int b) {
   return a + b;
}
public static double add(double a,int b) {
   return a + b;
}
public static double add(int a.double b) {
   return a + b;
}
public static int add(int a) {
   return a;
}
//同一个方法名,根据参数的类型和个数不同,返回不同的结果
double sum = add(2.5,3.5);
System.out.println(sum);
sum - add(1,2);
System.out.println(sum);

五.数组

(一)数组的概念及其特点

数组是相同类型数据的有序集合,数组描述的是相同类型的若干个数据按照次序排列组合而成。
数组是引用类型,也可以把数组看成是对象,数组中的每个元素相当于是该对象的成员变量。
java的对象是在中,因此数组无论是保存原始数据还是其他类型的数据,数组对象本身是在堆中存储的。
数组的特点:

  • 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  • 其元素必须是相同类型,不允许出现混合类型。
  • 数组类型可以是任何数据类型,包括基本类型和引用类型。

(二)数组的声明

数组声明:数据类型 数组名[] 或者[]数组名。
比如:int array[]或者int []array
数组声明的时候并没有实例化对象,只有实例化对象的时候java虚拟机JVM才会分配内存空间。
注意:声明数组并不意味创建后了一个数组,创建数组还要在声明数组的时候指定数组的长度。
标准的创建数组对象:数组的声明+new数组对象+指定数组长度(数组数据类型[指定长度])。

int arr[] = new int[10];

如果没有对数组进行初始化,那么数组会默认初始化,数组内每个元素的初始值与数据类型有关。

(三)数组的遍历

数组遍历可以使用for循环或者for-each循环

//for循环
int arr[] = new int[10];
for(int i = 0; i<arr.length;i++) {
   arr[i] = i * 2;
   System.out.println(arr[i] + "  ");
}
//for-each循环
String arrString[] = {"aaa","bbb","ccc","ddd"};
for(String s : arrString) {
    System.out.print(s + " ");
}
/*for-each使用的注意事项:
* 1.for-each是增强for循环,在遍历数组过程中不能修改数组中某元素的值,只能读取,不能修改。
* 2.for-each仅适用于遍历,不涉及有关索引(下标)的操作。
* */

(四)多维数组

多维数组可以看做是数组当中的数组,多维数组使用最多的是二维数组。
二维数组的创建和初始化和一维数组相同。

//二维数组静态初始化
int arrType[][] = new int [][] {
   {1,2,3},
   {4,5,6},
   {7,8,9}
};
//使用双重循环遍历二维数组
for(int i = 0; i< arrType.length; i++) {
   for(int j = 0; j < arrType.length; j++) {
      System.out.println(arrType[i][j] + " ");
}
      System.out.println();
}

六.面向对象

(一)面向对象的概念

1.面向对象和面向过程的区别:

  • 面向过程:面向过程是分析出解决问题的步骤,然后用函数把这些步骤一一实现。
  • 面向对象:把构成问题的事务按照一定的规则分为多个独立的对象,通过多个对象的相互配合来实现应用程序的功能,当需要改变这些功能的时候,只需要修改相应的对象就可以实现。

2.面向对象的三大特性:

  • 封装性:封装是面向对象的核心,将对象的属性和方法封装起来,不需要外界知道里面的具体实现细节,就是封装的思想所在。
  • 继承性:继承是类与类之间的一种关系,通过继承可以在无需编写原有类的前提下,对原有类进行扩展。使用继承可以增强代码的复用性,提高开发的效率。
  • 多态性:一个类中定义的属性和方法被继承之后,可以具有不同的数据类型或者表现出不同的行为,这使得同一属性和方法在不同类中具有不同的语义。

(二)类的定义和对象的创建

1.类和对象的关系:类是对象的抽象,用于描述一组对象的共同特征和行为。对象是类的实例化,一个类可以创建多个对象。
2.属性:属性也叫做类的成员变量,是用来描述对象的特征。
方法:方法也叫做类的成员方法,是从来描述对象的行为。

class Person { //定义类的关键字class
   int age = 20; //属性  成员变量
   void say() {  //方法  成员方法
     System.out.println("我今年" + age + "岁");
   }
}

3.对象的创建:类名 对象名 = new 类名();比如说Person p = new Person();此时就创建的一个对象叫做p,使用这个对象就可以引用类中定义的属性和方法。
注意:在实例化对象的时候,java虚拟机会自动为成员变量进行初始化操作,针对不同类型的成员变量,java虚拟机会赋予不同的初始值。
在这里插入图片描述

class Student {
  String name = "小明";
  int age = 18;
  public void introduce() {
    System.out.println("大家好,我叫" + name + "我今年" + age + "岁");
}
}
public class Test {
  public static void main(String[] args) {
     Person p = new Person();
     p.introduce();
}
}

注意:一个java项目可以创建多个类,但是只能有一个公共类,也就是只能用一个public定义的类。

(三)构造方法

1.构造方法的定义条件:

  • 方法名与类名相同
  • 方法前面没有返回类型的声明,不能使用return返回一个值,但是可以使用return作为方法的结束语句。
  • 构造方法的修饰符只能是public

2构造方法的重载
构造方法和普通方法一样也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或者参数个数不同即可。在创建对象的时候,可以通过调用不同的构造方法来为不同的属性赋值。

public class Test {
  public static void main(String[] args) {
    Person p1 = new Person();
    Person p2  = new Person("张三");
    Person p3 = new Person("李四",18);
}
}
class Person {
  public String name;
  public int age;
  public Person() {
     System.out.println("这是一个无参的构造函数");
} 
  public Person(String name) {
     this.name = name;
     System.out.prinln(name);
}
  public Person(String name,int age) {
     this.name = name;
     this.age = age;
     System.out.println(name + age);
}
}

注意:一个类可以创建多个构造方法,但是至少要有一个构造方法,如果没有定义构造方法,那么系统会自动为这个类创建一个默认的构造方法,这个默认的构造方法是无参的。

(四)this关键字

1.使用this关键字的原因:在一个类中通常会对一个属性或者变量进行统一命名,但是这样会导致全局变量和局部变量命名冲突问题,引入this关键字就可以很好解决这个问题。
2.this的三种用法:

  • 访问类的成员变量
  • 调用类的成员方法
  • 构造方法使用this

构造方法中使用this的注意事项:

  • 在构造方法中使用this调用其他构造方法,构造方法不能在成员中调用
  • 在构造方法中,使用this调用其他构造方法的语句必须放在第一行,而且只能出现一次
  • 同一类中的两个构造方法不能使用this互相调用
public class thisTest {
  public static void main(String[] args){
     Person p = new Person("张三");
     p.speak();
  }
}

class Person{
    int age;
    public Person(int age){ 
    //1.this的第一种用法:访问一个类的成员变量
        this.age=age;
    }
    public int getAge(){
        return this.age;
    }
    public void openMouth(){
        System.out.println("HelloWorld!");
    }
    public void speak(){
    //2.this的第二种用法:调用成员方法
        this.openMouth();
    }
    public Person(){
        System.out.println("调用默认无参数的构造方法!");
    }
    public Person(String name){
    //3.this的第三种用法:构造方法在实例化对象的时候会被自动调用,使用this([参数])可以在一个构造函数内调用另一个构造函数
        this();
        System.out.println("Hello"+name);
    }
}

(五)static关键字

使用static定义的变量,方法和类分别称为静态变量,静态方法和静态类。

  • 静态变量:静态变量的数据在内存中只有一份,而且能够被所有实例对象所共享,访问形式:类名.变量
  • 静态方法:在方法名前面使用static定义,就可以在不创建对象的情况下调用方法,访问形式:类名.方法名
  • 静态类:使用static修饰的类,通常使用static修饰的类都是匿名内部类。
  • 静态代码块:static {}
    注意:使用类被加载的时候,静态代码块就会执行,由于类只加载一次,所以静态代码块只会执行一次,通常使用静态代码块对类的成员变量进行初始化。

程序运行的顺序:

  • 先加载包含main方法的类

  • 然后加载类中创建静态代码块

  • 接着加载实例化对象的静态代码块,只会执行一次,与创建对象多少无关

  • 最后才是调用main()方法

public class staticTest {
    static {
    //首先执行公共类的静态代码块
        System.out.println("类1的静态代码块执行了!");
    }
    public static void main(String[] args){
        Student student=new Student();
        //student.name;实例对象不能调用静态成员
        Student.name="Jack"; //静态变量
        System.out.println(Student.name);
        Student.sayHello(); //静态方法
        //实例化了两个对象,但是静态代码块只执行一次
        Student student1=new Student();
      }
}
class Student{
    static{
        System.out.println("类2的静态代码块被执行了!");
    }
    public static String name;//创建静态变量
    public static void sayHello(){
        System.out.println("HelloWorld");
    }
}

(六)final关键字

final关键字的特征:

  • final关键是静态的意思,使用final修饰的变量和方法是不可改变的
  • final修饰的类不能够被继承
  • final修饰的方法不能被重写
  • final修饰的常量只能被赋值一次
public class finalTest {
   public static void main(String[] args) {
     final int number = 2;
     number = 4; //程序报错,final修饰的变量不能被改变
     Person p = new Person();
     p.sayName()
//注意:使用final修饰变量的时候,如果是局部变量可以不初始化,但是如果是修饰全局变量(成员变量)必须初始化
}
}
final class Animal {}
class Dog extends Animal {} //final修饰的类不能被继承
class Person {
  final String name = "Jack";
  public void sayName() {
    System.out.println("Hello 我的名字叫做" + name);
  } 
}
class Student extends Person {
//程序报错,final修饰的方法不能够被重写
  public void sayName() {}
}

(七)封装

封装的步骤:

  • 属性私有化:private 属性
  • 设置获取属性的方法get,获取属性需要设置返回值
  • 设置属性的方法set,带参数的方法,需要赋值给属性

通过设置公共修饰的get和set方法,外界就可以访问私有属性。

public class fz {
   public static void main(String[] args) {
       Student student = new Student();
       student.setName("张三");
       student.setAge(20);
       student.setSex("男");
       student.introduce();
   }
}
class Student {
//1.封装第一步:私有属性
  private String name;
  private int age;
  private String sex;
//2.封装第二步:设置get和set方法
  public String getName() {
     return name;
  }
  public void setName(String _name) {
     this.name = _name;
  }
  public int getAge() {
     return age;
  }
  public void setAge(int _age) {
     this.age = _age;
  }
  public String getSex() {
     return sex;
  }
  public void setSex(String _sex) {
     if(_sex == "男" || _sex == "女") {
          this.sex = _sex;
     }else {
          System.out.println("输入性别有误!!!");
     }
  }
  public void introduce() {
     System.out.println("姓名:"+this,name + " 性别:" + this.sex + " 年龄:" this.age);
  }
}

(八)继承

1.继承的相关概念:在java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的类叫做子类,现有类叫做父类,子类会自动拥有父类所有可以继承的属性和方法。
如果想声明一个类继承另一个类,使用关键字extends
2.类继承的注意事项:

  • java只支持单继承,不支持多继承,也就是说一个类只能有一个直接父类
  • 多个类可以继承同一个父类
  • java支持多层继承,就是一个类的父类可以再继承其他的类
  • 父类和子类是相对的概念,也就是说一个类是子类,有可能是另一个类的父类

3.重写:在继承关系中,子类会自动继承父类中定义的方法和属性,但是有时候子类需要在继承方法的基础上对继承的方法就行一些修改,这种操作就叫做重写。在子类重写方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。
4.super关键字:当子类重写父类的方法后,如果想访问父类的成员,就可以在子类中通过super关键字来实现。
使用super关键字的注意事项:

  • super关键字可以直接访问的是父类的成员变量、成员方法和构造方法
  • 使用super调用父类的构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次
  • 子类的构造方法一定会调用父类的构造方法,如果没有使用super指定调用哪种构造方法,那么子类实例化对象的时候,会自动调用父类的无参构造方法
  • 在定义类的时候。尽量定义一个无参的构造方法,避免继承时出现错误
public class superTest {
    public static void main(String[] args){
//当子类重写父类的方法时,子类对象无法访问父类被重写的方法,super关键字的作用就是用于访问父类的成员
        Animal animal=new Animal("动物");
        Dog dog=new Dog();
        animal.show();
        dog.printName();
    }
}
class Animal{
    String name="动物";
    public void show(){
        System.out.println("动物发出叫声!");
    }
    public Animal(String name){
        System.out.println("我是"+name);
    }
}
class Dog extends Animal{
    public void show(){
    //1.super的第一个用法:访问父类的成员方法
        super.show();
    }
    public void printName(){
    //2.super的第二个用法:访问父类的成员变量
        System.out.println(super.name);
    }
    public Dog(){
//3.super的第三个用法:访问父类的构造方法:super([参数1]、[参数2]、……)
        super("张三");
    }
}

(九)多态

多态:在同一个方法中,由于参数类型不同而导致运行结果不同。
在java中,为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据引用子类对象特征的不同,得到不同的运行结果。
在同一个方法中,由于参数类型不同而导致执行效果各异的现象就是多态,继承是多态实现的基础

public class dt {
  public static void main(String[] args) {
     Dog dog = new Dog();
     Cat cat = new Cat();
     animalShout(dog);
     animalShout(cat);
  }
  public static void animalShout(Animal animal) {
     animal.shout();
}
}
interface Animal {
  void shout();
}
class Dog implements Animal {
  @Override
  public void shout() {
    System.out.println("狗叫声。。。。。。");
  }
}
class Cat implements Animal {
  @Override
  public void shout() {
     System.out.println("猫叫声。。。。。。");
  }
}

(十)抽象类和接口

抽象类:当定义一个类的时候,需要要定义一些方法来描述类的特征,但是有的时候一些方法是无法确定,也就是不含有方法体。
关键字:abstract
抽象类的注意点:

  • 包含抽象方法的类必须是抽象类
  • 抽象类不可以实例化
  • 调用抽象类中定义的方法,需要创建子类,在子类中实现抽象类的抽象方法
  • 抽象类不一定要包含抽象方法,包含抽象方法的类必须是抽象类

接口:接口就是抽象类中所有的方法都是抽象方法,接口是由常量抽象方法组成的特殊类。
接口的目的就是为克服单继承的限制,虽然在java中,一个类只能有一个父类,但是可以实现多个接口,接口之间使用逗号隔开。
接口中的默认定义:
全局常量:public static final
方法:public abstract

public class Interface {
    public static void main(String[] args){
        Man man=new Man();
        man.sayHello();
        man.sayBay();
        //接口关键字:interface,实现接口的关键字:implements
        Dog dog=new Dog();
        dog.breath();
        dog.run();
        Elephant elephant=new Elephant();
        elephant.run();
        elephant.breath();
        elephant.Land();
    }
}
abstract class Persion{
    abstract void sayHello();//抽象类不能包含方法体
    public void sayBay(){ //接口可以包含非抽象方法
        System.out.println("baybay");
    }
}
class Man extends Persion{
    @Override
    void sayHello() {//子类可以对抽象方法进行实现
        System.out.println("HelloWorld");
    }

    @Override
    public void sayBay() {
        super.sayBay();
    }
}
interface Animal{
    void breath();//定义方法
    void run();
    String behavior="动物";//定义常量
}
class Dog implements Animal{
    @Override
    public void breath() {
        System.out.println(behavior+"呼吸");
    }

    @Override
    public void run() {
        System.out.println(behavior+"跑步");
    }
}
interface LandAnimal extends Animal{//接口之间可以继承
    void Land();
}
class Elephant implements LandAnimal{
    String AnimaName="大象";
    @Override
    public void run() {
        System.out.println(behavior+AnimaName+"在跑");
    }

    @Override
    public void breath() {
        System.out.println(behavior+AnimaName+"在呼吸");
    }

    @Override
    public void Land() {
        System.out.println(AnimaName+"是陆地动物");
    }
}

(十一)内部类

在java中允许在一个内部类中定义类,这样的类就叫做内部类,内部类所在的类称为外部类。
在内部类中,内部类可以在外部类中被使用,并且可以访问外部类中的成员。
匿名内部类:就是没有名字的内部类,但是在程序定义匿名内部类的时候,往往就直接创建了该类的对象,匿名内部类常常用于实现接口。
注意:外部类不可以直接访问内部的类成员,需要创建内部类对象才可以访问,外部类.内部类 对象名 = new 外部类().new 内部类();

class Out{
    private int number=2;
    class Inter{
        void show(){
            System.out.println("number="+number);//内部类可以调用外部类的成员
        }
    }
    public void test(){
        Inter inter=new Inter();//内部类可以在外部类中使用
        inter.show();
    }
}
interface Animal{
    void shout();
}
public class OutTest {
    public static void main(String[] args){
        Out out=new Out();
        out.test();
        Out.Inter inter=new Out().new Inter();
        inter.show();
        //匿名内部类
        animalShout(new Animal() {
            @Override
            public void shout() {
                System.out.println("喵喵喵!");
            }
        });//实际上就是调用方法,方法的参数为一个类:animalShout(new Animal(){方法});
    }
    public static void animalShout(Animal animal){
        animal.shout();
    }
}

七.异常

(一)异常类

java程序中提供了大量的异常类,这些异常类都是继承java.lang.Throwable类。
Throwable类有两个直接子类:

  • Error类:错误类,表示java运行时产生的系统内部错误或资源好尽的错误,是比较严重的,仅靠修改程序本身是不能恢复程序的。
  • Exception类:异常类,表示序本身可以处理的错误,在java中,Exception类有大量的子类,除了Runtime类是运行时异常,其他都是编译时异常。

(二)try catch finally

处理异常的常用方式就使用try catch finally语句。

  • try:出现一次的代码的放在try语句中
  • catch:捕获异常,然后可以打印异常的详细信息。在catch语句中,可以指定对应的异常类,也可以使用exception类,打印异常详细的方法是getMessage()。
  • finally:最后一定会执行的语句就放在finally中,除非在finally之前使用了System,out(0);退出当前java虚拟机,finally语句才不会执行。
public class ExceptionTest {
    public static void main(String[] args){
        try {
            double s=divide(2,0);
            System.out.println(s);
            double s1=divide(2,2);//发生异常后面的代码不会执行
            System.out.println(s1);
        }catch (Exception e){
            System.out.println("捕获到的异常:"+e.getMessage());//getMessage():返回throwable的详细消息(String类型)
            return;
        }finally {
            System.out.println("程序继续执行!");
        }
    }
    public static int divide(int x,int y){
        int result=x/y;
        return result;
    }
}

注意:在catch代码块中使用return,那么return以后的语句都不会执行,但是不会影响finally语句。

(三)throws

处理异常的另外一种方式是抛出异常,throws关键字需要写在方法声明的后面,声明方法发生异常的类型。
throws抛出异常实际是抛给调用发生异常的方法,在调用这个方法的地方来处理异常(上级)。
注意:throws和throw的区别

  • throw声明在方法内部,而throws声明在方法声明的处
  • throw只能用于抛专出一种异常,而throws可以抛出多个异属常
  • throw需要用户自己捕获相关的异常,而throws不要显示捕获异常,系统自动将不会的异常抛给上级
public class throwTest {
    public static void main(String[] args){
        //throws关键字需要写在方法声明的后面,throws后面需要声明方法中发生异常的类型,通常称为抛出一个异常
        int result = 0;
        try {
            result = divide(1,0);
        } catch (Exception e) {
            e.printStackTrace();

        }
        System.out.println(result);

    }
    public static int divide(int x,int y) throws Exception{
        int result=x/y;
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值