Java基础

JAVA基础

Java特性和优势

  • 简单性
  • 面向对象
  • 可移植性
  • 高性能
  • 分布式
  • 动态性
  • 多线程
  • 安全性
  • 健壮性

Java三大版本

JavaSE:标准版(桌面程序、控制台开发等)

JavaME:嵌入式开发(手机、小家电等)

JavaEE:E企业级开发(web端、服务器开发等)

基础

注释

  • 项目复杂的时候一定要用到注释,这样方便自己或者他人理解
  • 注释不会被执行
  • 写注释是一个非常好的习惯

三种注释:

单行注释

多行注释

文档注释

public class Demo1 {
    //这是单行注释

    /* 这是
       多行
       注释
     */

    /**javadoc:文档注释
     * @author bitz2
     */
}

标识符

关键字

在这里插入图片描述

java所有的组成部分都需要名字、类名、变量名及方法名都被称为标识符。

  • 所有标识符都应该以字母(A-Z或者a-z)、美元符号($)、或者下划线(_)开始
  • 首字符之后可以使字母(A-Z或者a-z)、美元符号($)、或者下划线(_)或数字的任何字符组合
  • 不能使用关键字作为变量名或方法名
  • 标识符是大小写敏感的
  • 合法标识符例如:age 、 $salary、 _value 、 _2_value
  • 非法标识符例如: 123ab 、-salary、#abc

数据类型

强类型语言:要求变量的使用要严格符合规定,所有变量都必须先定义后使用

弱类型语言

java的数据类型分为:基本类型引用类型
在这里插入图片描述

类型转换

由于java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。

由低到高:

byte,short,char→int→long→float→double

运算中,不同类型的数据先转化为同一类型,然后再运算。

  public static void main(String[] args) {
        int i=128;
        double a=i;
        //强制转换 高--低
        //自动转换 低--高
        System.out.println(i);
        System.out.println(a);
  }

变量

变量就是可以变化的量。

Java是一种强类型语言,没个变量都必须声明其类型。

Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。

type varName [=value] [{,varName[=value]}];
//数据类型  变量名 = 值  可以使用逗号隔开来声明多个同类型变量

注意事项

  • 每个变量都有类型,类型可以是基本类型,也可以是引用类型
  • 变量名必须是合法标识符
  • 变量声明是一条完整的语句,因此每一个声明都必须以分号结束

变量的命名规范

  • 所有变量、方法、类型:见名知意
  • 类成员变量:首字母小写和驼峰原则:monthSalary
  • 局部变量:首字母小写和驼峰原则
  • 常量:大写字母和下换线:MAX_VALUE
  • 类名:首字母大写和驼峰原则:Man, GoodMan
  • 方法名:首字母小写和驼峰原则:run() , runRun()

运算符

算术运算符:+,-,*,/,%,++,–

赋值运算符:=

关系运算符:>,< ,>=, <=, ==,!=instanceof

逻辑运算符:&&,||,!

位运算符:&,|,^,~,>>,<<,>>>(了解)

条件运算符:?,:

扩展赋值运算符:+=,-=,*=,/=

包机制

  • 为了更好的组织类,Java提供了包机制,用于区别类名的命名空间
  • 包语句的语法格式为:
package pkg1[.pkg2[.pkg3...]];
  • 一般利用公司域名倒置作为包名
  • 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包,使用“import”语句
import package1[.package2....].(classname|*);

JavaDoc

javadoc命令是用来生成自己API文档

参数信息

  • @author 作者名
  • @version 版本号
  • @since 指明需要最早使用的jdk版本
  • @param 参数名
  • @return 返回值情况
  • @throws 异常抛出情况

流程控制

Scanner对象

可以通过Scanner类来获取用户的输入。

基本语法:

Scanner s = new Scanner(System.in);

通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。

import java.util.Scanner;
public class practice1 {
    public static void main(String[] args) {
        //创建一个扫描对象,接受键盘数据
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用next方法接收:");

        //判断用户有没有输入字符串
        if (scanner.hasNext()){
            //使用next方法接收
            String str= scanner.next();
            System.out.println("输出的内容为:"+str);
        }
        //凡是属于IO流的类如果不关闭会一直占用资源
        scanner.close();
    }
}
import java.util.Scanner;
public class practice2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用nextline方式接收:");

        if (scanner.hasNextLine()){
            String str = scanner.nextLine();
            System.out.println("输出的内容为:"+str);
        }
        scanner.close();
    }
}

顺序结构

  • Java的基本结构就是顺序结构,除非特别指明,否则就按瞬狙一句一句执行。
  • 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。

选择结构

  • if单选泽结构

语法:

if(布尔表达式){
    //如果布尔表达式为true将执行的语句
}
  • if双选择结构

语法:

if(布尔表达式){
    //如果布尔表达式的值为true
}else{
    //如果布尔表达式的值为false
}
  • if多选择结构

语法:

if(布尔表达式1){
    //如果布尔表达式1的值为true执行代码
}else if(布尔表达式2){
    //如果布尔表达式2的值为true执行代码
}else if(布尔表达式3){
    //如果布尔表达式3的值为true执行代码
}else{
    //如果以上布尔表达式都不为true执行代码
}
  • 嵌套的if结构

语法:

if(布尔表达式1){
    //如果布尔表达式1的值为true执行代码
    if(布尔表达式2){
        //如果布尔表达式2的值为true执行代码
    }
}
  • switch多选择结构

switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

switch语句中的变量类型可以是:byte,short,int或char

语法:

switch(expression){
    case value: //语句
        break;//可选
    case value:
        break;
      //可以有任意数量的case语句
    default://语句  可选
}

循环结构

while循环
while(布尔表达式){
    //循环内容
}
  • 只要布尔表达式为true,循环就会一直执行下去
  • 大多数情况下我们会让循环停止,需要一个表达式失效的方式来结束循环
  • 少部分情况需要一直循环,例如服务器的请求响应监听等
  • 循环条件一直为true就会造成无线循环(死循环),我们正常的业务编程中应该尽量避免死循环
do…while循环
do{
    //代码语句
}while(布尔表达式)

do…while循环和while循环相似,不同的是,do…while循环会至少执行一次。

两者区别:while先判断后执行,dowhile先执行后判断,dowhile总是保证循环体会至少被执行一次。

For循环
for(初始化;布尔表达式;更新){
    //代码语句
}
  • for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构。
  • for循环执行的次数是在执行前就确定的。

小练习:for循环打印99乘法表

public class fordemo3 {
    public static void main(String[] args) {
        //打印99乘法表
        //先用for循环第一列
        //固定1 再套入for循环
        //调整换行
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <=i; j++) {
                System.out.print(j+"*"+i+"="+(j*i) +"\t");
            }
            System.out.println();
        }
    }
}
增强for循环
for(声明语句:表达式){
    //代码
}
  • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
  • 表达式:表达式是要访问的数组名,或者返回值为数组的方法。
break、continue、goto
  • break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

  • continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。

  • 关于goto关键字

1.goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子—带标签的break和continue。

2.对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

3.“标签”是指后面跟一个冒号的标识符 例如 label:

方法

什么是方法

Java方法是语句的集合,他们在一起执行一个功能。

  • 方法是解决一类问题的步骤的有序组合
  • 方法包含于类或对象中
  • 方法在程序中被创建,在其他地方被引用

设计方法原则:方法的本意是功能块,就是实现某个功能的语句块的集合。设计方法时最好保证方法的原子性,就是一个方法只完成一个功能。

方法的定义和调用

Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

  • 修饰符∶修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
  • 返回值类型∶方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有
    返回值。在这种情况下,returnValueType是关键字void。
  • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
  • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的
    参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
    形式参数:在方法被调用时用于接收外界输入的数据。
    实参:调用方法时实际传给方法的数据。
  • 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}
public class Demo1 {
    public static void main(String[] args) {

        /**调用静态类
         *直接调用Student.say()
         */

        //调用非静态,实例化这个类new
        Student student = new Student();
        student.say();  // 对象类型 对象名  对象值

    }
}

方法调用

  • 调用方法:对象名.方法名(实参列表)
  • Java支持两种调用方法的方式,根据方法是否返回值来选择
  • 当方法返回一个值的时候,方法调用通常被当做一个值。

例如:

int larger = max(20,30);
  • 如果方法返回值是void,方法调用一定是一条语句。
System.out.println("Hello,kevin");

方法的重载

重载就是在一个类中,有相同的函数名称,但形参不同的函数。

实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

方法的重载的规则:

  • 方法名称必须相同。
  • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
  • 方法的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为方法的重载。

命令行传参

有时候想要运行一个程序时再传递给它消息,这要靠传递命令行参数给main()函数来实现。

public class CommandLine{
    public static void main(String args[]){
        for(int i=0;i<args.lenth;i++){
            System.out.printlin("args["+i+"]:"+args[i]);
        }
    }
}

可变参数

  • 在方法声明中,在指定参数类型后加一个省略号(…)。
  • 在一个方法中只能指定一个可变参数,他必须是方法的最后一个参数,任何普通的参数必须在它之前声明。

递归

A方法调用B方法,我们很容易理解!
递归就是:A方法调用A方法!就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为
一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所
需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象
的无限集合。
递归结构包括两个部分:
**递归头:**什么时候不调用自身方法。如果没有头,将陷入死循环。
**递归体:**什么时候需要调用自身方法。

练习:

public class Demo4 {
    public static void main(String[] args) {
         //递归思想
        System.out.println(f(5));
    }
    //递归适合小量运算,大额计算能不用递归就不用
    public  static int f(int n){
        if (n==1){
            return 1;
        }else{
            return n*f(n-1);
        }
    }
}

数组

定义

  • 数组是相同类型数据的有序集合。
  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
  • 每一个数据称作一个数组元素,没个数组元素可以通过一个下标来访问他们。

数组声明创建

  • 首先必须声明数组变量,才能在程序中使用数组
dataType[] arrayRefVar;  //首选的方法
或者 dataType arrayRefVar[];  //效果相同,但不是首选方法
  • Java语言使用new操作符来创建数组
dataType[] arrayRefVar = new dataType[arraySize];
  • 数组的元素是通过索引访问的,数组索引从0开始
  • 获取数组长度 arrays.length

练习:

public class Demo1 {
    public static void main(String[] args) {
        int[] num = new int[10]; //创建一个数组
        //给数组赋值
        num[0]=1;
        num[1]=2;
        num[2]=3;
        num[3]=4;
        num[4]=5;
        num[5]=6;
        num[6]=7;
        num[7]=8;
        num[8]=9;
        num[9]=10;

        //计算所有元素和
        int sum=0;
        for (int i = 0; i < num.length; i++) {
            sum=sum+num[i];
        }
        System.out.println("总和为"+sum);
    }
}

三种初始化和内存分析

三种初始化
  • 静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
  • 动态初始化
int[] a = new int[2];
a[0]=1;
a[1]=2;
  • 数组的默认初始化

数组是引用类型,它的元素相当于类的实例变量,新词数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

内存分析

在这里插入图片描述

下标越界及小结

数组四个基本特点
  • 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  • 其元素必须是相同类型,不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
  • 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
    数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,
    数组对象本身是在堆中的。
数组边界
  • 下标的合法区间 [0,length-1],如果越界就会报错
  • ArratIndexOutOfBoundsException:数组下标越界异常
小结
  • 数组是相同数据类型(数据类型可以为任意类型)的有序集合
  • 数组也是对象。数组元素相当于对象的成员变量
  • 数组长度的确定的,不可变的。如果越界,则报:ArrayIndexOutofBounds

数组使用

  • For-Each循环
public class ArrayDemo1{
    int[] arrays = {1,2,3,4,5};
    for(int array: arrays){
        System.out.println(array);
    }
}
  • 数组作方法入参
 //打印数组元素
    public static void printArray(int[] arrays){
        for (int i = 0; i < arrays.length; i++) {
            System.out.print(arrays[i]+" ");
        }
    }
  • 数组作返回值
  //反转数组
public static int[] reverse(int[] arrays){
          
   int[] result = new int[arrays.length];
     //反转的操作
    for (int i = 0,j= result.length-1; i < arrays.length; i++,j--) {
           result[j] = arrays[i];
    }
          return result;
}

多维数组

  • 多维数组可以看作是数组的数组,比如二维数组就是一个特殊的一维数组,其每个元素都是一个一维数组
  • 二维数组
int a[][] = new int[2][4];

Arrays类

  • 数组的工具类java.util.Arrays
  • 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了-个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
  • 查看JDK帮助文档
  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而”不用"使用对象来调用(注意:是"不用”而不是“不能")
  • 具有以下常用功能:
    ◆给数组赋值:通过fill方法。
    ◆对数组排序:通过sort方法,按升序。
    ◆比较数组:通过equals方法比较数组中元素值是否相等。
    ◆查找数组元素: 通过binarySearch方法能对排序好的数组进行二分查找法操作。
import java.util.Arrays;

public class Demo3 {
    public static void main(String[] args) {
       int[] a={1,5,3,12,50,66,102,42};
        //System.out.println(Arrays.toString(a));  输出数组元素
        Arrays.sort(a); //对数组元素排序
        System.out.println(Arrays.toString(a));
        
        Arrays.fill(a,0);
        System.out.println(Arrays.toString(a));
    }
}

冒泡排序

import java.util.Arrays;
public class Demo4 {
    public static void main(String[] args) {
        int[] a={1,5,2,3,11,20,33,52,70,15,45,26};
        int[] sort = sort(a);  //对上面数组进行排序
        System.out.println(Arrays.toString(sort)); //用toString方法输出数组
    }
 //冒泡排序
 //比较数组中两个相邻的元素,如果第一个数比第二个数大,就交换位置
    public static int[] sort(int[] array){
       //定义临时变量
        int temp=0;
        //外层循环,判断比较多少次
        for (int i = 0; i < array.length-1; i++) {
           //通过flag标识来减少没有意义的比较
            boolean flag=false;
            //内层循环,比较两个数大小
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j+1]<array[j]){  //从小到大排序
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                    flag=true;
                }
            }
             if (flag==false){
                 break;
             }
        }
        return array;
    }
}

稀疏数组

◆当-个数组中大部分元素为0,或者为同- -值的数组时,可以使用稀疏数组来保存该数组。
◆稀疏数组的处理方式是:
◆记录数组一共有几行几列,有多少个不同值
◆把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

面向对象

面向过程&面向对象

面向过程思想

  • 步骤清晰简单,第一步做什么,第二步做… .

  • 面对过程适合处理一-些较为简单的问题

    面向过程思想

  • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进
    行单独思考。最后,才对某个分类下的细节进行面向过程的思索。

  • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

    对于描述复杂的事物,为了从宏观.上把握、从整体上合理分析,我们需要使用面向对象的思路
    来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

面向对象本质就是:以类的方式组织代码,以对象的组织(封装)数据。

三大特性:封装、继承、多态

类与对象

类与对象的关系

类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一 个具体的事物.

动物、植物、手机、电脑…
Person类、Pet类、 Car类等,这些类都是用来描述/定义某-类具体的事物应该具备的特
点和行为
对象是抽象概念的具体实例
◆张三就是人的-个具体实例,张三家里的旺财就是狗的-个具体实例。
◆能够体现出特点展现出功能的是具体的实例,而不是一个抽象的概念

创建与初始化对象

◆使用new关键字创建对象
◆使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化
以及对类中构造器的调用。
◆类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩
个特点:

  1. 必须和类的名字相同

  2. 必须没有返回类型,也不能写void

    package com.oop.Demo02;
    //一个项目应该只存在一个main方法
    public class Application {
        public static void main(String[] args) {
            Student2 s1 = new Student2();
            s1.setName("Kevin");
            System.out.println(s1.getName());
    
            s1.setAge(22);
            System.out.println(s1.getAge());
    
        }
    }
    

构造器

package com.oop.Demo02;
public class Person {
     //一个类即使什么都不写,它也会存在一个方法
    //显示的定义构造器
    String name;
    //1.使用new关键字,本质是在调用构造器
    //2.用来初始化值
    public  Person(){
    }
    //有参构造:一旦定义了有参构造,无参就必须显示定义
    public  Person(String name){
        this.name = name;
    }
}
/*
 public static void main(String[] args) {
        //new 实例化了一个对象
        Person person = new Person("Kevin");
        System.out.println(person.name);
    }
    构造器:
    1.和类名相同
    2.没有返回值
    作用:
    1.new本质在调用构造器
    2.初始化对象的值
    注意点:定义了一个有参构造之后,如果想使用无参构造,就显示定义一个无参构造
    构造器快捷键 Alt+Insert
 */

小结类与对象

package com.oop.Demo02;

public class Demo {

    /*
    1. 类与对象
    类是一个模板,抽象的  对象是一个具体的实例

    2.方法
    定义、调用

    3.对应的引用
    引用的类型  包括:类(对象)、接口、数组。
    基本类型(8):
    整数型(4种):byte、short、int、long、
    浮点型(2种):float、double
    字符类型(1种):char
    布尔类型(1种):boolean

    对象是通过引用来操作的  栈-->堆

    4.属性  字段field 成员变量
    默认初始化
       数字: 0  0.0
       char: u0000
       boolean: false
        引用: null
        修饰符 属性类型 属性名 = 属性值

    5. 对象的创建和使用
       必须使用new关键字来创造对象   构造器  Person kevin=new person();
       对象的属性    kevin.name
       对象的方法   kevin。sleep()

    6.类
       静态的属性  属性
       动态的行为  方法
      ‘封装、继承、多态’

     */
}

封装

我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏)
◆通常, 应禁止直接访问-个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
◆属性私有, get/set

public class Student2 {

    /*
1.封装提高程序安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.提高系统可维护性
 */

    private String name;
    private  int age;
    private char sex;
    private  int id;

    public String getName(){
       return this.name;
   }
    public  void  setName(String name){
    this.name = name;
}
   //alt+insrt


    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>130 || age<0){
            this.age=3;
        }else
        this.age = age;
    }
}

继承

  • 继承的本质是对某-批类的抽象, 从而实现对现实世界更好的建模。
  • extands的意思是"扩展”。子类是父类的扩展。
  • JAVA中类只有单继承,没有多继承。
  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
  • 继承关系的俩个类, 一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extend s来表示。
  • 子类和父类之间,从意义上讲应该具有"is a"的关系。
  • object类
  • super
  • 方法重写
super注意点:
1. super调用父 类的构造方法,必须在构造方法的第一个
2. super 必须只能出现在子类的方法或者构造方法中!
3. superthis 不能同时调用构造方法!
Vs this:
代表的对象不同:
this:
本身调用者这个对象
super:
代表父类对象的应用
前提
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this() ; 本类的构造
super():父类的构造!
重写:需要有继承关系,子类重写父类的方法!
1.方法名必须相同
2.参数列表列表必须相同
3.修饰符:范围可以扩大但不能缩小:
pub1ic>Protected>Default>private
4.抛出的异常:范围,可以被缩小,但不能扩大; ClassNotFoundException --> Exception()
重写,子类的方法和父类必要一致;方法体不同!

多态

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

  • 多态存在的条件

    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
  • 注意:多态是方法的多态,属性没有多态性。

  • instanceof (类型转换)引用类型,判断一个对象是什么类型。

/*
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系类型转换星常! ClassCastException !
3.存在条件: 继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();
        1. static 方法,属于类,它不属于实例
        2. final 常量;
        3. private 方法;
*/

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
  • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
//abstract  抽象类:类 extends :   单继承~   (接口可以多继承)
public abstract class Action {
//约束~有人帮我们实现~
//abstract,抽象方法,只有方法名字,没有方法的实现!
public abstract void doSomething( );
  //1. 不能new这 个抽象类,只能靠子类去实现它;约束!
  //2. 抽象类中可以写普通的方法~
  //3. 抽象方法必须在抽象类中~
  //抽象的抽象:约柬~
}

接口

◆普通类:只有具体实现
◆抽象类:具体实现和规范(抽象方法)都有!
◆接口:只有规范!
◆接口就是规范,定义的是- -组规则, 体现了现实世界中“如果你是…则必须能…"的思想。如果你是天使,
则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
◆接口的本质是契约,就像我们人间的法律一样。 制定好后大家都遵守。
◆00的精髓,是对对象的抽象,最能体现这一点的就是接口。 为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++. java. c#等) ,就是因为设计模式所研究的,实际上就是如何合理的去抽象。

内部类

◆内部类就是在-个类的内部在定义-个类,比如,A类中定义- -个B类,那么B类相对A类来说就
称为内部类,而A类相对B类来说就是外部类了。
◆1. 成员内部类
◆2. 静态内部类
◆3.局部内部类
◆4. 匿名内部类

异常机制

简单分类

以下三种类型的异常:
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。
例如要打开一个不存在文件时,- 个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常:运行时异常是可能被程序员避免的异常。 与检查性异常相反,运行时异常可以在
编译时被忽略。
错误ERROR:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,
当栈溢出时,-一个错误就发生了,它们在编译也检查不到的。

Error

  • Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
  • Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError.这些异常发生时,Java虚拟机(JVM) -般会选择线程终止。
  • 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError) 、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。

Exception

  • 在Exception分支中有-个重要的子类RuntimeException (运行时异常)

    • ArraylndexOutOfBoundsException (数组下标越界)

    • NullPointerException (空指针异常)

    • ArithmeticException (算术异常)

    • MissingResourceException (丢失资源)

    • ClassNotFoundException (找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。

  • 这些异常- -般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;

  • Error和Exception的区别: Error通常是 灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机 (JVM) - -般会选择终止线程; Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

异常处理机制

  • 抛出异常
  • 捕获异常

异常处理五个关键字:

try、catch、finally、throw、throws

自定义异常

  • 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
  • 在程序中使用自定义异常类,大体可分为以下几个步骤:
    1.创建自定义异常类。
    2.在方法中通过throw关键字抛出异常对象。
    3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理; 否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
    4.在出现异常方法的调用者中捕获并处理异常。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值