Java学习

目录

 

1.  Eclipse中的快捷键        

2.输出

3.输入

4.数据类型

5.计算

6.优先级

7.类型转换

8.比较、判断

9.循环

*带标签的break&&continue

*boolean

10.数组

*创建数组

 *数组变量

数组的输出

*for-each循环遍历

11.字符

12.包裹类型

*Character:

 *Math类  :

13.字符串

*字符串连接

*输入字符串

*比较

*字符串操作

*获取String的长度

*访问字符串里面的单个字符

*遍历循环字符串

*得到子串

*寻找字符

*其他String操作

*在switch-case中使用字符串

14.函数

*传入的参数类型不匹配

其他

1在CMD中编译运行java

2关于进制

Arrays工具类的使用

单元测试

        步骤

内存解析

 面向对象

1面向过程(POP)与面向对象(OOP)

        概念

        三大特征

2Java基本元素:类和对象(面向对象的核心概念)

        概念

        常见的类的成员

3对象的创建和使用

        对象的内存解析

        匿名对象

4类的成员之一:属性

属性(成员变量)vs 局部变量

5类的成员之二:方法

如何定义方法

6再谈方法

        方法的重载(overload)

        可变形参的方法

        **方法参数的传递机制

        递归方法

7OOP特征之一:封装与隐藏

        问题引入

         封装性的体现

        四种权限修饰符

8类的成员之三:构造器

        构造器的作用

        总结属性赋值的先后顺序

        拓展:JavaBean&&UML

9关键字:this

        this修饰属性和方法

        this调用构造器

10关键字:package、import

        package

         import (导入)

11OOP特征二:继承性(extends)

        好处

        格式

        体现

12方法的重写(override)

        定义

        要求

13四种访问权限修饰符

14关键字:super(父类的)

        调用属性和方法

        调用构造器

15子类对象实例化过程

        从结果上看(继承性)

        从过程上看

16OOP特征三:多态性

        对象的多态性

        多态的使用 

        如何才能调用子类中特有的属性和方法

        instanceof操作符

        多态性的使用前提

17Object类的使用

        功能(equals/toString)

                 ㈠==和equals的区别

18包装类的使用

        基本数据类型与、包装类与String类间的转换

         自动装箱/自动拆箱

        基本数据类型,包装类---->String

        String---->基本数据类型,包装类

        鬼题

19关键字:static

        static修饰属性:  静态变量

        static修饰方法:静态方法

        单例设计模式

20理解main方法的语法

21类的成员之四:代码块

        代码块的作用

        静态代码块vs非静态代码块

        代码块,构造器执行顺序问题 

        属性赋值的先后问题 

22关键字:final

        final修饰类

        fianl修饰方法

        final修饰变量

23抽象类与抽象方法(abstract)

        abstract修饰类(抽象类)

        abstract修饰方法(抽象方法)

        abstract使用的注意点

        抽象类的匿名子类

        模板方法设计模式 

24接口(interfere)

        概述 

         使用

        JDK8中接口可以定义静态方法,默认方法

25类的成员之五:内部类

        概念 

 成员内部类

        关注如下三个问题

异常处理 

1异常概述与异常体系结构

        Error 

         Exception

 2常见异常

3异常处理机制一:try-catch-finally

        抓抛模型

        注意事项

4异常处理机制二:throws

         格式

        体会

        方法重写规则之一

        开发中如何选择使用try-catch-finally 还是使用throws?

5手动抛出异常:throw

6用户自定义异常类

          如何自定义异常类

​编辑 Exercise9_10毁灭吧

 多线程

1.基本概念:程序,进程,线程

        概念 

        单核CPU和多核CPU 

        使用多线程的优点

        何时需要多线程

                 ​编辑

2.线程的创建与使用

                Thread类中有关方法

        多线程的创建

        线程的调度 

3.线程的生命周期

4.线程的同步

5.线程的通信

6.JDK5.0新增线程创建方法

集合 

1Java集合框架概述

2Collection接口方法

3Iterator迭代器接口

4Collection子接口一:List

5Collection子接口二:Set

6Map接口

7Collections工具类

常用类 (详见PPT)

1 字符串相关的类

        String类

        String的常用方法

        String与其他类进行转换

        StringBuffer

        StringBuilder

2JDK8之前的日期时间API

        System静态方法

        Date类

        Calendar类

        SimpleDateFormat类

3JDK8中日期时间API

        LocalDate,LocalTime,LocalDateTime

        Instant

        DateTimeFormatter

        其他类

4Java比较器

        Comparable接口

        Comparator接口

5System类

6Math类

7BigInteger与BigDecimal


 

1.  Eclipse中的快捷键        

 

             * 1.补全代码的声明:Alt + /
             * 2.快速修复:Ctrl + 1
             * 3.批量导包:Ctrl + Shift + o
             * 4.使用单行注释:Ctrl + /
             * 5.使用多行注释:Ctrl + Shift + /
             * 6.取消多行注释:Ctrl + Shift + \
             * 7.复制指定行的代码:Ctrl + Alt + down 或Ctrl + Alt + up//上下键
             * 8.删除指定行代码:Ctrl + d
             * 9.上下移动代码:Alt + up 或 Alt + down
             * 10.切换到下一行代码空位:Shift + 回车
             * 11.切换到上一行代码空位:Ctrl + Shift + 回车
             * 12.查看源码:Ctrl + 鼠标指定的结构 或 Ctrl + Shift + t
             * 13.退回到前一个编辑的页面:Alt + left
             * 14.进入到下一个编辑页面:Alt + right
             * 15.光标选择指定的类,查看继承树的结构:Ctrl + t
             * 16.复制代码:Ctrl + c
             * 17.撤回代码:Ctrl + z
             * 18.反撤回代码:Ctrl + y
             * 19.剪切:Ctrl + x
             * 20:粘贴:Ctrl + v
             * 21.保存:Ctrl + s
             * 22.全选:Ctrl + a
             * 23.格式化代码:Ctrl + Shift + f
             * 24.选中数行整体往后移:Tab
             * 25.选中数行整体往前移:Shift + Tab
             * 26.在当前类中,显示类结构,并支持搜索指定的方法、属性等:Ctrl + o
             * 27.批量修改指定的变量名、方法名、类名等:Alt + Shift + r
             * 28.选中结构中的大小写的切换:变成大写:Ctrl + Shift + x
             * 29.选中结构中的大小写的切换:变成小写:Ctrl + Shift + y
             * 30.调用生成getter/setter/构造器等结构:Alt + Shift +s
             * 31.显示当前选择资源(工程 or文件)的属性:Ctrl + enter
             * 32.快速查找:参照选择中的Word快速定位到下一个:Ctrl + k
             * 33.关闭当前窗口:Ctrl + w
             * 34.关闭所有窗口:Ctrl + Shift + W
             * 35.查看指定结构使用过的地方:Ctrl + Alt + g
             * 36.查找与替换:Ctrl + f
             * 37.最大化当前的View:Ctrl + m
             * 38.直接定位到当前行的首行:Home
             * 39.直接定位到当前行的末尾:End

————————————————

2.输出

System.out.print("");
System.out.println("");//自动换行
int sum = 3.1415926;
System.out.println(""+sum);
System.out.println("%.2f",sum);//四舍五入

3.输入

        Scanner in = new Scanner(System.in);

Scanner in = new Scanner(System.in);
System.out.println(in.nextline());

         *对于char类型的获取,Scanner没有相关的方法,只能获取一个字符串

4.数据类型

        常量:final int ...

b52ed8f7710f4970824c4a0485446d78.png

        long l = 1233728208038L

         整数默认int,小数默认double

5.计算

System.out .println(2+3+"=2+3="+(2+3));
int price,amount;
amount = in.nextInt();
price = in.nextInt();
System.out.println(amount+"-"+price+"="+(amount-price));

6.优先级

20e9d25e4e1848d1b8a7bc5f45e5aa11.png

7.类型转换

        ①int->double: 自动/(double)( )

        ②double->int: (int)( )

double a;
int b;
b = in.nextInt();
a = in.nextInt();
a = in.nextDouble();
b = (int)(a);

8.比较、判断

Scanner in = new Scanner(System.in);
int amount=in.nextInt();
System.out.println(amount>=10);
//输入:10
//输出结果:true

        ==和!=优先级最低,连续的运算符从左到右执行判断

浮点数比较

System.out.println(Math.abs(f1-f2),0.00001);//判断两个浮点数是否相等
if(amount>=0)
    System.out.println("fighting");

if-else

if-else-if

switch-case

9.循环

        for循环

        while循环

        do-while循还

*建立随机数

int count = (int)Math.random()*100  //[0,1)->[0,100)

*带标签的break&&continue

        退出多重循环

        (在循环前可以放一个标号来表示循环,带标号的break和continue对那个循环起作用)

OUT://标号
for(i=1;i<n;i++)
{
    for(j=0;j<n;j++)
    {
        for(k=0;k<n;k++)
            {
                if(i+j+k>n)
                   break OUT;
            }
    }
}

*boolean

boolean isprime = true;
boolean[] a = new boolean[100]; 
isprime = false;
if(isprime)
{
    System.out.print(" ");
}

10.数组

*创建数组

        *数组长度

int[] number = new int[100];//创建数组
int[] score  = {1,2,3,4,5,6};
int[][] a = new int[2][3];
number[i] = a;
for(i=0;i<number.length;i++)//number.length为数组长度

String arr = new String[2][];
arr[0] = new String[4];

 *数组变量

        数组变量是数组的管理者而非数组本身

        数组创建出来后必须交由数组变量管理

        数组变量之间的比较可以判断是否为同一数组(地址相同)

int[] a1 = new int[10];
int[] a2 = a1;

5ebeb995bf314ae38e41ea013c2836db.png

        如果要复制数组,必须用遍历!!!

数组的输出

        1.遍历输出
        2.直接数组名输出:System.out.println(数组名);//只有char型可以用,否则会输出内存地址。
        3.带格式输出:System.out.println(Arrays.toString(数组名));//适用任意类型数组,但输出的内容是带格式的,元素与元素之间有逗号隔开。

*for-each循环遍历

        for(<类型><变量> : <数组>)...

        !!!不能改变数组的值

for(int k : a)//每次循环将a里面的值赋值给k  (第一次:k=a[0]...)
{
    if(k=x)
    ...
}

11.字符

char c = \u0040   
//  /u指Unicode编码,0040是八进制

62ca9443966e407cb1b939e67435baf5.png

         *\t    :到下一个表格位,上下对齐(不是空四个)

12.包裹类型

        对于基本数据类型,Java提供了对应的包裹(wrap)类型。这些包裹类型将一个基本数据类型的数据转换成对象的形式,从而使得它们可以像对象一样参与运算和传递

7e89e3385f264f208e278e04bdd3eabf.png

        除了int和char以外,包裹类型就是把基本类型的名字的第一个字母大写。在Java的系统类库中,所有第一个字母大写的,都是类的名字 

        *包裹类型的用处:

        获取该类型的最大最小值

System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);

        * .  :当需要用一个类或者对象做事情的时候,用.坐运算符

a.length
Integer.MAX_VALUE

*Character:

d51acafa0fd74ff78c241d0faf6d2d1d.png

System.out.println(Character.isdigit('1'));
System.out.println(Character.toLowerCase('A'));

 *Math类  :

        abs / pow / random(获取0-1之间的数) / round(四舍五入)

13.字符串

        *字符串变量:

aeeca0ba869943388e0cfa3ddd63246e.png78759d1314324249996c225449ba6f37.png

 

String str1 = new String("a string");
String str2 = "hello";
char[] str3 = new char[5];
System.out.println("hello"+"world");
System.out.println(1+2+"hello");
//创建了一个String的对象
//用“a string”初始化这个对象
//创建管理这个对象的变量s
//让s管理这个对象

        String不能用for-each循环来遍历

        char可以 

*字符串连接

        + : 当这个+的一边是字符串而另一边不是时,会将另一边表达为字符串然后做连接(八种数据类型

String s = "Hello";
int num = 1002;
String w = s + num;//boolean只能与字符串做连接运算
System.out.print(s+num);

System.out.println("* *");//* *
System.out.println('*'+'\t'+'*');//93,转换成ASCLL做加法
System.out.println('*'+"\t"+'*');//* *

*输入字符串

35dbcd7c6965430387cd95297413d66c.png

Scanner in = new Scanner(System.in);
String s;
s = in.next();

        对象变量的赋值

*比较

        ==:比较是否是同一个

        equals:比较是否具有相同的内容

        compareTo:比较两个字符串谁大谁小

String s = reader.getInput();
if(input.equals("bey")
{
...
System.out.println(s1.compareTo(s2));
System.out.println("abcd".compareTo(s2));
//如果s1<s2,那么结果为负,s1==s2,结果为0,s1>s2,结果为正
System.out.println(s1.compareToIgnoreCase(s2));
//不区分大小写来比较大小

*字符串操作

         字符串是对象,对它的所有操作都是通过“ . ”这个运算符来进行

        格式:字符串.操作

*获取String的长度

        length()函数:str.length

String str = "";//length为0
String ser;//ser.length Error!
System.out.print(str.length());

*访问字符串里面的单个字符

        charAt(index):s.charAt(index)

        //返回在index上的单个字符,index∈[0,length-1],不能用for-each循环来遍历字符串

        (for-each只能对于数组)

*遍历循环字符串

for(int i=0;i<s.length();i++)
{
...

*得到子串

        [0,...]

System.out.println(s.substring(n));//得到从n号位置到末尾的全部内容
System.out.println(s.substring(b,e));//得到从b号位置到e号位置之前的内容[b,e)

*寻找字符

50a8154f9d9e4689bfb674b2f2d1f6e2.png

 

String s = "0123456789";
System.out.println(s.indexOf('4'));
System.out.println(s.indexOf("234"));

*其他String操作

4d25285c09fe415fae63598291754265.png

         所有的字符串都是不可变的,对它们的操作的结果都是制造新的字符串出来(不是对字符串本身做变化)

*在switch-case中使用字符串

switch(s)
{
    case"this":...
    case"that":...
    ...
}

14.函数

String s = "hello";
int i = s.length();
Ssytem.out.print(s+"bey");
//这些都写对象在执行函数

        函数是一块代码,接收0个或多个参数,做一件事情,并返回0个或一个值

public static <返回类型> <函数名>(<参数>)
{
    ...
}

*传入的参数类型不匹配

        当函数期望的参数类型比调用函数时给的值的类型宽(字节长度)的时候,编译器能悄悄替你把类型转换好

byte-->char-->short-->int->long-->float-->double

        *当byte,char,short三种变量做运算时,结果类型要为int

        当函数期望的参数类型比调用函数时给的值的类型窄的时候,需要你写强制类型转换

        (int)5.0

        当函数期望的参数类型与调用函数时给的值的类型之间无法转换的时候-->不行!

其他

1在CMD中编译运行java

        编写:将java代码保存在以“.java”结尾的源文件中

        编译:使用javac.exe命令编译我们的java源文件,格式:javac 源文件名.java

        运行:使用java.exe命令解释运行我们的字节码文件,格式:java 类名 

         在一个java源文件中可以声明多个class,但是,最多只能有一个类声明为public,而且要求声明为public的类的类名一定要与源文件名相同

2关于进制

        二进制:0,1,逢二进一,以0b或者0B开头

        十进制

        八进制:0-7,满8进1,以数字0开头

        十六进制:0-9以及A-F,满16进1,以0x或0X开头,此处A-F不区分大小写

Arrays工具类的使用

        java.util.Arrays类即为操作数组的工具类,包含了用来操作数组的各种方法

9e40724ff40345d9b62e54846b9c4e68.png

单元测试

        步骤

                1.选中当前工程 - 右键选择:build path - addlibraries - JUnit 4 - 下一步 

               2. 创建Java类,进行单元测试。此时的Java类要求,此类是public的,并且提供公共的无参的构造器

                3.此类中声明单元测试方法。此时的单元测试方法,方法权限是public,没有返回值,没有形参

                4.此单元测试方法上需要声明注解:@test,并在单元测试类导入import org.junit.Test 

                5.声明好单元测试方法以后,就可以在方法体内测试相关的代码

                6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnitTest

                7.没有异常,绿条;有,红条、

                8.直接写,然后加。。。。 

内存解析

          栈:存局部变量

          堆:new出来的结构:对象,数组

          方法区:类的加载信息,静态域,常量池

 面向对象

        三条主线:

                java类及其类的成员:属性,方法,构造器,代码块,内部类

                面向对象的三大特征:封装性,继承性,多态性,(抽象性)

                其他关键字:this,super,static,final,abstract,interface,package,

1面向过程(POP)与面向对象(OOP)

        概念

                面向过程(Procedure Oriented Programming):强调的是功能行为,一函数为最小单位,考虑怎么做。

                面向对象(Object Oriented programming):将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

        三大特征

                封装(Encapsulation)、继承(Inheritance)、多态(Polymorphism)

2Java基本元素:类和对象(面向对象的核心概念)

        概念

                类(Class):对一类事物的描述,是抽象的,概念上的定义。

                对象(Object):是实际存在的该类事物的每个个体,因而也称为实例

                        *面向对象的程序设计重点是类的设计,类的设计其实就是类的成员的设计

                        *java中用class来描述事物,

        常见的类的成员

                 属性:对应类中的成员变量(field)

                 行为:对应类中的成员方法(method)

一个类在另一个类中声明,这是关联关系

//Account.java
class Account{
    private int account;
}
//Bank.java
class Bank{
    private Account account;
}

3对象的创建和使用

        1.创建类,设计类的成员

        2.创建类的对象

        3.通过“对象.属性”/“对象.方法”调用对象的结构

public class XXXX {
	public static void main(String[] args) {
		// TODO Auto-generated method stub	
		//创建Person类的对象
		Person p1 = new Person();
		//调用属性
		Scanner in = new Scanner(System.in);
		p1.language = in.next();
		p1.is = true;
		//调用方法
		p1.lang(p1.language);
		p1.lang("China");
		p1.eat();

        //多个对象
        Person p2 = new Person();
        Person p3 = p1;//将p1的地址赋给p3
	}
}
//类的创建
class Person{
	String language;
	boolean is ;
	public static void eat() {
		System.out.print("eat");
	}
	public static void lang(String language) {
		System.out.println(language);
	}
}

​

        *如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的) 

        对象的内存解析

ab3a7526213347a49297421c6b13cb8d.png

 356a5b8b11c442018619743e2fff9150.png

        匿名对象

                没有显示的赋给一个变量名,只能调用一次

​
public class test{
    public static void main(String[] arg){
        Phone p1 = new Phone();

        p1.eat;
        p1.play;

        new Phone();
        new Phone.eat();
        new Phone.play();//两个不同的变量

        Use(new Phone());//匿名对象的一般使用
    }

    public void Use(Phone phone){
        phone.eat();
        phone.play();
    }
}
class Phone{
    public void eat(){
        System.out.print("eat");
    }
    public void play(){
        System.out.print("play");
    }
}

​

4类的成员之一:属性

属性(成员变量)vs 局部变量

        相同点

                1.定义变量的格式:数据类型 变量名 = 变量值

                2.先声明,后使用

                3.变量都有其对应的作用域

        不同点

                1. 在类中声明的位置不同

                        属性:直接定义在类的一对{}内,不在方法内。

                        局部变量:声明在方法内,方法形参,代码块内,构造器形参,构造器内部

                        的变量。

                2.关于权限修饰符的不同

                        属性:可以在声明属性时,指明其权限,使用权限修饰符。

                                   常用的权限修饰符:private、public、缺省、protected。

                        局部变量:不可以使用权限修饰符。

                3.默认初始化值的情况

                        属性:类的属性,根据其类型,都有默认初始化值。

                                   整型:0;浮点型:0.0;字符型:0(或'\u000');布尔型:false;引用数据类型:null

                        局部变量:没有初始化值(在调用之前就要赋值)

                4.在内存中加载的位置

                        属性:加载到堆空间(非static中)

                        局部变量:加载到栈空间

5类的成员之二:方法

        Math类:sqrt()、random()...

        Scanner类: .nextXxx() ...

        Arrays类 ...

如何定义方法

权限修饰符 返回值类型 方法名(形参){

方法体

                                                }

//方法的声明
public void eat(){}
public void sleep(int hour){}
public String getname(){}
public String Nation(String nation){}

6再谈方法

        方法的重载(overload)

                定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不相同(与权限修饰符,返回值类型无关)

        可变形参的方法

                 格式:数据类型 ...数据名称

                *传入的参数个数可以为0个,1个,2个...

                *可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载

                *可变个数形参在方法的形参中,必须声明在末尾,且只能声明一个

public class MoreXincan {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MoreXincan test = new MoreXincan();
		test.show("hello");
		test.show("hello","world");
		test.show();
	}
//	public void show(String s) {
//		System.out.print("sh");
//	}
	public void show(String...arg) { //(String[] arg)
		System.out.print("wu");
	}
    public void show(int i,String...arg){
    }//(String...arg,int i)是错的

        **方法参数的传递机制

                关于变量的赋值

                        变量是基础数据类型:此时赋值的是变量所保存的数据值

                        变量是引用数据类型:此时赋值的是变量所保存的数据的地址值

        方法参数的传递机制:值传递

        递归方法

public class ObjectShuzu {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student[] stu = new Student[20];//****声明Student类型的数组
		for(int i=0;i<stu.length;i++) {
			stu[i] = new Student();//****给数组元素赋值
			stu[i].num = (int)(Math.random()*100);//给Student对象的属性赋值
		}
		for(int i=0;i<stu.length;i++)
		{
			System.out.print(stu[i].num+" ");
		}
	}

}
class Student{
	int num;

        在本类中不用重新制造对象,在本类使用其他类的属性或方法要制造对象 

7OOP特征之一:封装与隐藏

        高内聚,低耦合

        问题引入

                当我们创建一个类的对象之后,我们可以通过“对象.属性”的方式对对象的属性进行赋值。这里,赋值操作要受到数据类型和存储范围的制约。除此之外,没有其他的制约条件。但是,在实际问题中,我们往往需要给属性赋值,加入额外的限制条件。这个条件就不能在属性声明时体现,只能通过方法进行限制条件的添加,同时要避免使用“对象.属性”的方式对属性进行赋值,则需要将属性声明为私有的(private)---->封装性的体现

                //对属性进行封装(比如腿的个数不能为负)

//对属性进行限制(比如腿的个数不能为负)
public class Restrict {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Animal a = new Animal();
		a.name = "刘宇峥";
		a.age = 11;
		Scanner in = new Scanner(System.in);
		int l = in.nextInt();
		a.setleg(l);
		System.out.print(a.name);
		if(a.leg>=0)
			System.out.print("是个正常人,有"+a.leg+"条腿");
		else
			System.out.print("不是个正常人");
	}

}
class Animal{
	String name;
	int age;
	private int leg;//腿的数量,对leg进行封装
	public void setleg(int l) {//leg的接口
		if(l>=0)
			leg = l;
		else
			leg = -1;
	}
    public int Getleg(){
        return leg;
    }
}

         封装性的体现

                1.将类的属性私有化(private)

                2.提供公共的(public)方法来获取(GetXxx)和设置(SetXxx)

        四种权限修饰符

修饰符类内部同一个包不同包的子类同一个工程
privateyes   
(缺省)yesyes  
protectedyesyesyes 
publicyesyesyesyes

                        *对于class(类)的权限修饰只能用public和default(缺省)

                        *public可以在任意地方被访问

                        *default类只可以被同一个包内部的类访问

                        *子类对象的访问权限要大于父类的访问权限

                4种权限可以用来修饰类和类的内部结构:属性,方法,构造器,内部类

8类的成员之三:构造器

        构造器的作用

                构建对象

                        1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器

                        2.定义构造器的格式:权限修饰符 类名(形参列表){ }                

                                Person p = new Person();//(new + 构造器)

                        3.一个类中定义多个构造器,彼此构成重载

                        4.一旦显式的定义了类的构造器之后,系统不再提供默认的空参构造器

                        5.一个类中至少有一个构造器

                给属性做初始化

public class Constructor {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a=2;
		Person p = new Person(a);
	}
}

class Person{
	//属性
	int age;
	//构造器
	public Person() {
		
	}
	public Person(int a) {
		age = a;
	}
	//方法
	public void eat() {
		System.out.print("eat");
	}
}

        总结属性赋值的先后顺序

               (一点都不严谨,离谱)

                1.默认初始化

                2.显式初始化

                3.构造器中初始化

                4.通过“对象.方法”或“对象.属性”赋值 

        拓展:JavaBean&&UML

                ⒈JavaBean是一种Java语言写成的可重用组件

                ⒉所谓JavaBean是指符合如下标准的Java类

                       ①类是公共的

                       ②有一个无参的公共的构造器

                        ③有属性,且有对应的get,set方法

3382e35d96b94347a09d0b0b31a405c1.png

c61f31874ea3460198837d8927f60c61.png

9关键字:this

                this可以用来修饰属性、方法和构造器

        this修饰属性和方法

                this理解为:当前对象或当前正在创建的对象(构造器)

                在类的方法(构造器)中,我们可以用“ this.属性 ”或“ this.方法 ”调用当前(正在创建的)对象的属性或方法。但是,通常情况下,都选择省略“ this ”。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用“ this.变量 ”的方式,表明此变量是属性,而非形参。

        this调用构造器

               ①我们在类的构造器中,能够显式的使用" this(形参列表) ”方式,调用本类中指定的其他构造器

                ②构造器中不能通过调用" this(形参列表) ”方式自己

                ③如果一个类中有n个构造器,则最多有n-1构造器使用了" this(形参列表) ”

                ④规定:" this(形参列表) ”必须声明在当前构造器的首行

                ⑤构造器内部最多只能声明一个" this(形参列表) ”,用来调用其他的构造器

对属性进行限制(比如腿的个数不能为负)
public class Restrict {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Animal a = new Animal();
	}

}
class Animal{
    //属性
    private String name;
	private int leg;
    //构造器
    public Animal(){
        //Animal初始化时,需考虑如下的1、2、3、4...(共40行代码)
    }
    public Animal(String name){
        //Animal初始化时,需考虑如下的1、2、3、4...(共40行代码)
        this();//调用构造器,来避免冗杂重复40行代码的问题
        this.name = name;
        this.setname();
    }
    public Animal(int leg,String name){
        //Animal初始化时,需考虑如下的1、2、3、4...(共40行代码)
        this(name);//调用构造器
    }
    //方法
	public void setleg(int leg) {
        this.leg = leg;
	}
    public int Getleg(){
        return this.leg;
    }
    public void setname(String name){
        this.name = name;
    }
    //Source->Generate Getters and Setters
}

10关键字:package、import

        package

                         ①为了更好的实现项目中类的管理,提供包的概念

                         ②使用package声明类或接口所属的包

                         ③包,属于标识符,遵循标识符的命名规则

                         ④每“ . ”一次,就代表一层文件目录

                         ⑤同一个包下,不能命名同名的接口、类;不同的包下,可以命名同名的接口、类

9b99e0557aff4fbdb3d55870c1127ae9.png

         import (导入)

                1.在源文件中显式的使用import结构导入指定包下的类,接口

                2.声明在包的声明和类的声明之间

                3.如果需要导入多个结构,则并列写出即可 

                4.可以使用“ xxx.* ”的方式,表示可以导入xxx包下的所有结构,但是如果使用的是xxx子包下的结构,则仍需要显式表示

                5. 如果使用的类或接口是java.lang包下定义的,则可以省略import结构

                6.如果使用的类或接口是本包下定义的,则可以省略import结构

                7.如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显式

                8.import static: 导入指定类或接口中的静态结构(属性或方法)

import java.util.*;
import com.atguigu.exer4.Account;
//全类名的方式显式
com.atguigu.exer3.Account acct = new com.atguigu.exer3.Account(1000,200,0.12);

import static:java.lang.System.*;
import static:java.lang.Math.*;

out.println("hello");//out:属性
long num = round(123.456);//round:方法

11OOP特征二:继承性(extends)

        好处

                减少了代码的冗余

                便于功能的扩展

                为之后的多态性的使用,提供了前提

        格式

                class A extends B{ }

                        A:子类(派生类)subclassB:父类(基类)superclass

        体现

                ①一旦子类A继承父类B之后,子类A就获取到了父类B中声明的所有电脑属性和方法

                ②私有的属性或方法也可以继承,但由于封装性的影响,需要通过方法来获取,不能直接调用

                ③子类继承父类之后,还可以定义自己特有的属性或方法、

                ④java只支持单继承和多层继承

                ⑤如果我们没有显示的声明一个类的父类的话,则次类继承与java.lang.Object类,所有的java类(除java.lang.Object类)都直接或间接的继承于java.lang.Object类

class Person{
    String name;
	int age;
	public Person() {
		
	}
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	public void eat() {
		System.out.println("eat");
	}
	public void sleep() {
		System.out.print("sleep");
	}
}

class Student extends Person{
//	String name;
//	int age;
    String major;
    //构造器不能继承,省略
	public Student() {
		
	}
	public Student(String name,int age,String major) {
		this.name = name;
		this.age = age;
        this.major = major;
	}

//	public void eat() {
//		System.out.println("eat");
//	}
//	public void sleep() {
//		System.out.print("sleep");
//	}
}

12方法的重写(override)

        定义

                在子类中可以根据需要从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法覆盖父类的方法

        要求

                方法的声明:权限修饰符 返回值类型 方法名(形参列表)throws 异常的类型{ };

                约定俗成:子类中的叫重写的方法,父类中叫被重写的方法

                ①子类重写的方法的方法名和形参列表与被重写的方法的方法名和形参列表相同

                ②子类重写的方法的权限修饰符可以比被重写的方法的权限修饰符更大

                        >特殊情况:子类不能重写父类中声明为private权限的方法

                ③返回值类型

                        >父类被重写的方法的返回值类型是void,则子类中的返回值类型只能是void

                        >父类被重写的方法的返回值类型是A类型,则子类中的返回值类型可以是A类或A类的子类

                        >父类被重写的方法的返回值类型是基本数据类型,则子类中的返回值类型必须是相同的基本数据类型

                ④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

13四种访问权限修饰符

        (见封装与隐藏)

14关键字:super(父类的)

        super可以用来调用:属性,方法,构造器

        调用属性和方法

                ①可以在子类的方法或构造器中,通过使用“super.属性”或“super.方法”的方式,显式的调用父类中声明的属性或方法。但是,在通常情况下,都习惯省略“super”。

                ②特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用“super.属性”的方式,表明调用的是父类中声明的属性

                ③特殊情况:当子类重写了父类中的方法后,我们想在子类中调用父类中被重写的方法时,则必须显式的使用“super.方法”的方式,表明调用的是父类中被重写的方法。

        调用构造器

                ①可以在子类的构造器中显式的使用“ super(形参列表)”的方式,表示调用父类声明的指定的构造器

                ②“ super(形参列表)”的使用必须声明在子类构造器的首行

                ③在一个类的构造器中,针对于this(形参列表)或super(形参列表)只能二选一

                ④在构造器的首行没有显示的声明this(形参列表)或super(形参列表),则默认调用的是“ super()”

                 ⑤在类的多个构造器中,至少有一个类的构造器中使用了“ super(形参列表)”

15子类对象实例化过程

        从结果上看(继承性)

                子类继承父类以后,就获得了父类中声明的属性或方法

                创建子类的对象,在堆空间中,就会加载所有父类中声明的属性

        从过程上看

                我们通过子类的构造器创建子类对象是,我们一定会直接或间接的调用其父类的构造器,进而调用父类的构造器。直到调用到了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。

16OOP特征三:多态性

        (一个事物的多种形态)

        对象的多态性

                父类的引用指向子类的对象/子类的对象赋给父类的引用(可以直接应用在抽象类和接口上)***相当于用一个更大的范围去形容一个更具体的对象(子类特有的方法不能调用)

Person p = new Man();
//其中Person是父类,Man是子类
p.eat();//调用的是子类重写父类的方法
//p是子类的对象,是父类的类型

        多态的使用 

                当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法---虚拟方法调用

                虚拟方法的调用(动态绑定):子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法。父类根据赋给它的不同的子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

                有了对象的多态性后,内存中实际是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,我们在编译期,只能调用父类中声明的方法,但在运行期,实际执行的是子类重写父类的方法(编译,看左边;运行,看右边)

        如何才能调用子类中特有的属性和方法

                使用强制类型转换符(向下转型)

Person p2 = new Man();
Man m1 = (Man)p2;

                 使用情景:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行强制类型转换

        instanceof操作符

                判断对象a是否是类A的实例。是,返回true。

                         如果a instanceof A返回true,则a instanceof B也返回true,其中B是A的父类

02f217cb31f8463e927546e2138aee03.png

 

        多态性的使用前提

                类的继承关系

                要有方法的重写

为什么要有多态性:避免代码的冗余

                对象的多态性只适用于方法,不适用于属性(属性不存在多态性)

public class DuoTaiXin {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
			func(new Dog());
			func(new Cat());
	}
	public static void func(Animal1 animal) {
		animal.eat();
		animal.walk();
	}
//	public static void func(Dog dog) {
//		dog.eat();
//		dog.walk();
//	}
//	public static void func(Cat cat) {
//		cat.eat();
//		cat.walk();
//	}
}
class Animal1{
	public void eat() {
		System.out.println("吃饭");
	}
	public void walk() {
		System.out.println("叫");
	}
}
class Dog extends Animal1{
	public void eat() {
		System.out.println("吃骨头");
	}
	public void walk() {
		System.out.println("汪汪汪");
	}
}
class Cat extends Animal1{
	public void eat() {
		System.out.println("吃鱼");
	}
	public void walk() {
		System.out.println("喵喵喵");
	}
}

20bf7cd56f314934b04a09d4d63f0b5b.png

17Object类的使用

        1.Object是所有类的根父类(数组也作为Object类的子类出现,可以调用Object类中的方法)

        2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类

        3.Object类的功能(属性,方法)具有通用性 

        功能(equals/toString)

                1.equals() / toString() / getClass() / hashCode() / clone():复制一个对象

025bd464003348baaf65038cbe43c5c7.png

                 ㈠==和equals的区别

                        ①==:可以使用在基本数据类型和引用数据类型变量中

                                1.如果比较的是基本数据类型,比较两个变量保存的数据是否相等(不一定类型要相等)

                                2.如果比较的是引用数据类型,比较两个对象的地址值是否相等

		int i = 10;
		int j = 10;
		double k = 10.0;
		System.out.println(i==j);//true
		System.out.println(i==k);//true
		
//		boolean w = true;
//		System.out.println(i==w);
		
		char c = 10;
		System.out.println(i==c);//true
		
		char c1 = 65;
		char c2 = 'A';
		System.out.println(c1==c2);//true

                equals:是一个方法,而非运算符,只适用于引用数据类型

                                1.Object类中equals()的定义

                                        public boolean equals(Object obj){

                                                return (this==obj);

                                        }//说明:Object类中定义的equals()和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个个体

                                2.重写Object的equals

                                        通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的“实体内容”是否相等。那么,我们就需要对Object类中的equals()进行重写。

001eb15bc1954ced81d7b1df28f7b25e.png

 

                                3.String类中equals()即为比较内容是否相同

		String str1 = new String("aaaa");
		String str2 = new String("aaaa");
		System.out.println(str1==str2);//false
		System.out.println(str1.equals(str2));//true
		
		Person p1 = new Person();
		Person p2 = new Person();
		System.out.println(p1.equals(p2));//false

                       ㈡ toString

                                1.当我们输出一个对象的引用时,实际上就是调用当前对象的toString()方法

                                2.Object类中toString的定义:

                                public String toString() {

                                         return getClass().getName()+"@"+Integer.toHexString(hashCode());
                                 }//说明:Object中toString()方法与System.out.println(atr)一样输出地址值

                                3.在String、Date、File、包装类等都重写了Object类中的toSting()方法 

                                4.重写toString 

18包装类的使用

        针对八种基本数据类型定义相应的引用数据类型--包装类

        基本数据类型与、包装类与String类间的转换

c1edbf1c96bf4c938e19715b9d8ca2b7.png

         自动装箱/自动拆箱

int num = 10;
Integer in1 = num;//自动装箱
int num1 = in;//自动拆箱

        基本数据类型,包装类---->String

int num = 10;
//方式一:连接运算
String Str1 = num+" ";
//方式二:调用String的valueOf(Xxx xxx)
float f1 = 12.3f;
String str2 = String.valueOf(f1);//"12.3"

        String---->基本数据类型,包装类

String str1 = "123";
//调用包装类的parseXxx(String s)
int num = Integer.parseInt(str1);
Syso(num+1);

String str2 = "true";
boolean b = Boolean.parseBoolean(str2);//可能会爆NumberFormatException

        鬼题

//1.
Object o1 = true?new Integer(1):new Double(2.0);
System.out.println(o1);//1.0    三目运算符自动提升类型

//2.
Object o2;
if(true)
    Integer(1);
else
    Double(2.0);//1

//3.
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j);//false

//Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],保存了从-128到127范围内的整数,如果我们使用自动装箱的方式,给Integer赋值的范围在-128到127范围内是,可以直接使用数组中的元素
Integer m = 1;
Integer n = 1;
syst.out.println(m==n);//true

Integer x = 128;//想当于new了一个对象
Integer y = 128;
System.out.println(x==y);//false

 详解:https://zhuanlan.zhihu.com/p/538300264 

b5e022e4735d4ec3b9dad424c99aa3b8.png

 详解:http://"C:\Users\姜九笙\eclipse-workspace\hello\src\Exercise5\ScoreTest.java"

关于可以直接将Object o1 = true:

java中Object o1=true为什么是正确的?_百度知道

https://blog.csdn.net/weter_drop/article/details/105179308

19关键字:static

        1.static:静态的

        2.static可以用来修饰:属性、方法、代码块、内部类   

        static修饰属性:  静态变量

                1.属性按是否使用static修饰又分为:静态属性(类变量)vs非静态属性(实例变量)

                       ①实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性时,不会导致其他对象中同样的属性值的修改。

                        ②静态变量:我们创建了类的多个对象,多个对象共享一个静态变量当通过某一个对象修改静态变量时,会导致其他对象调用次静态变量时,是修改过的。

                        ③其他说明:静态变量随着类的加载而加载

                                          静态变量的加载要早于对象的创建

                                          由于类只加载一次,则静态变量在内存中也只会存在一份,存在方法的静态域中

可调用的类变量/静态方法实例变量/非静态方法
yesno
对象yesyes

        static修饰方法:静态方法

                1.随着类的加载而加载,可以通过 类.静态方法 的方式进行调用

                2.静态方法中,只能调用静态的方法或属性。

                   非静态方法中,既可以调用非静态方法或属性,也可以调用静态方法或属性。

                3.在静态的方法中,不能使用this/super关键字

                4.关于静态属性和静态方法的使用。从生命周期的角度去理解

                *在开发中,如何确定一个属性是否要声明为static的?

                        >属性可以被多个对象所共享的,不会随着对象的不同而不同

                        >类中的常量也常常声明为static

                *在开发中,如何确定一个方法是否要声明为static的?

                        >操作静态属性的方法,通常设置为static

                        >工具类中的方法,习惯上声明为static的。比如:Math,Arrays,collections

        单例设计模式

cd0aeffb26cc4da1922fc880ff971f2b.png

                 饿汉式vs懒汉式

                        饿汉式:坏处:对象加载时间过长。好处:是线程安全的

                        懒汉式:好处:延迟对象的创建。坏处:线程不安全-->到多线程时,再修改

20理解main方法的语法

        main()方法的使用:

                1.main()方法作为程序的入口

                2.main()方法也是一个普通的静态方法

                3.main()方法可以作为我们与控制台交互的方式

21类的成员之四:代码块

        代码块的作用

                用来初始化类,对象

                        代码块如果有修饰的话,只能用static。因此分为静态代码块和非静态代码块

        静态代码块vs非静态代码块

                静态代码块

                        >可以有输出语句

                        >随着类的加载而执行,而且只执行一次

                        >作用:初始化类的信息

                        >如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行

                        >静态代码块的执行优先于非静态代码块的执行

                        >只能调用静态的属性,方法,不可以调用非静态的 

                非静态代码块

                        >可以有输出语句

                        >随着对象的加载而执行

                        >每创建一个对象,就执行一次

                        >作用:可以在创建对象时,对对象的属性等进行初始化

                        >如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行 

                        >可以调用静态的,非静态的属性和方法 

static{

}
{

}

        代码块,构造器执行顺序问题 

                静态代码块优于非静态代码块优于构造器

                父类先于子类,静态先于非静态,代码块先于构造器

                (构造器:创建对象过程中,等非静态代码块初始化结束,才执行构造器的主题代码

                    非静态代码块:在创建对象的同时执行)

                静态代码块只在第一次new的时候执行,之后再创建对象也不会执行,但是非静态代码块在每次创建对象的时候都会执行一次

        属性赋值的先后问题 

                默认初始化-显式初始化/在代码块中赋值-构造器中初始化- 通过对象初始化

22关键字:final

        final(最终的):可以修饰类、方法、变量 

        final修饰类

                此类不能被其他类继承 (例如:String类,System类...)

final class Finala{

}

        fianl修饰方法

                该方法不能再被重写 (例如:Object类中的getclass();

public final void show(){

}

        final修饰变量

                 此时的变量就称为常量

                1.final修饰属性

                        可以考虑的位置有:显式初始化、代码块中初始化、构造器中初始化

    //显式初始化
    final int NUM = 0;
    //代码块中初始化
    final  int LEFT;
    {
    LEFT=10;
    }
    //构造器中初始化
    public FinalTest(){
        LEFT =1;
    }

        2.final修饰局部变量

                尤其是使用final修饰形参时,表明此形参是一个常量,当我们调用此方法时,给常量形参赋一个实参以后,就只能在方法体内使用此形参,不能改变其值

public void show(){
final int NUM=10;
}
public void show(final int num){

}

         static final:用来修饰属性,全局常量

                static final+属性:全局常量

        final修饰对象Java中Final修饰对象 - 百度文库

23抽象类与抽象方法(abstract)

        随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计,应该保证父类和子类能够共享特征,有时将一个父类设计的非常抽象,以至于他没有具体的实例,这样的类叫做抽象类
        abstract可以用来修饰:类,方法

        abstract修饰类(抽象类)

                >此类不能实例化

                >抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)

                >开发中,都会提供抽象类的子类,让子类对象实例化,完成相关操作

        abstract修饰方法(抽象方法)

                >抽象方法只有方法的声明,没有方法体

                >包含抽象方法的类一定是个抽象类;反之,抽象类中可以没有抽象

方法。

`               >若子类重写的父类中的所有的抽象方法,则此子类方可实例化;若子类没有重写父类中的所有抽象方法,则此子类也是一个抽象类,需要用abstract修饰。

        abstract使用的注意点

、             >abstract不能用来修饰属性,构造器等

                >abstract不能用来修饰私有方法(不能重写),静态方法(不叫重写),final的方法(不能重写

abstract class Person{
    public abstract void eat();
}

        抽象类的匿名子类

​		Worker worker  = new Worker();
		method(worker);//非匿名的类非匿名的对象
		
		method(new Worker());//非匿名的类匿名的对象
		
		//创建了一匿名子类的对象:p
		Person2 p = new Person2() {
			@Override
			public void eat() {
				System.out.println("eat");
			}
		};
		method(p);
		
		//创建匿名子类的匿名对象
		method(new Person2() {
			@Override
			public void eat() {
				System.out.println("eat.");
			}
		});
	}

	public static void method(Person2 p) {
		p.eat();
	}

}
abstract class Person2{
	public abstract void eat();
}
class Worker extends Person2{
	@Override
	public void eat() {
		
	}
	
}

        模板方法设计模式 

3c8beddb616e4d689a84d5a5b16536d1.png

                 见hello的TemplateTest,****Exercise8*****

 

24接口(interfere)

        概述 

22ae4f99b2ca4aee88162a965b0f722b.png

         使用

                1.接口使用interface来定义

                2.Java中,接口和类是并列的两个结构

                3.如何定义接口:JDK7以前,只能定义全局常量和抽象方法

                                            JDK8,除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法

                4.接口中不可以定义构造器,意味着接口不能实例化

                5.Java开发中,接口通过让类去实现(implements)的方式来使用,如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化...

                6.Java类可以实现多个接口--->弥补了Java单继承性的局限性

                        格式:class AA extends BB implements CC,DD{ }

                7.接口与接口之间可以继承,而且可以多继承

                8.接口的具体使用,体现多态性

                9.接口,实际上可以看做是一种规范

interface Flyable{
	//全局常量
	public static final int MAX_SPEED = 7900;//宇宙第一速度
	int MIN_SPEED = 1;//书写时可以省略public static final
	//抽象方法
	public abstract void fly();
	void stop();//省略public abstract
	
//	Interfaces cannot have constructors,不能创建构造器
//	public Flyable(){
//		
//	}
}
interface Attackable{
	void attack();
}
class Plane implements Flyable{
	@Override
	public void fly() {
		System.out.println("通过引擎起飞");
	}
	@Override
	public void stop() {
		System.out.println("停");
	}
	
}
class BUllet extends Plane implements Flyable,Attackable,CC{
	@Override
	public void fly() {		
	}
	@Override
	public void stop() {
	}
	@Override
	public void attack() {
	}
	@Override
	public void method1() {
	}
	@Override
	public void method2() {
	}
}
interface AA{
	void method1();
}
interface BB{
	void method2();
}
interface CC extends AA,BB{
	
}
public class USBTest {
	public static void main(String[] args) {
			Computer computer = new Computer();
			USB flash = new Flash();//多态
			computer.transfereData(flash);
	}
}
class Computer{
	public void transfereData(USB usb) {//多态的体现
		usb.start();
		System.out.println("具体传输数据");
		usb.end();
	}
}
interface USB{
	void start();
	void end();
}
class Flash implements USB{
	@Override
	public void start() {
		System.out.println("U盘已启动");
	}
	@Override
	public void end() {
		System.out.println("U盘已安全弹出");
	}
}
			Computer computer = new Computer();
			//创建了接口非匿名实现类的的非匿名对象
			Flash flash = new Flash();
			computer.transfereData(flash);
			//创建了接口的非匿名实现类的匿名对象
			computer.transfereData(new Printer());
			//创建了接口的匿名实现类的非匿名对象
			USB phone = new USB() {
				@Override
				public void start() {
					System.out.println("手机已启动");
				}
				@Override
				public void end() {
					System.out.println("手机已关机");
				}
			};
			computer.transfereData(phone);
			//创建了接口的匿名实现类的匿名对象
			computer.transfereData(new USB() {
				@Override
				public void start() {
					System.out.println("音响已启动");
				}
				@Override
				public void end() {
					System.out.println("音响已关机");
				}
			});

                代理模式:见NetWork.java

                练习:Exercise9

9e980da0b0c044959f9a8a1a0237f297.png

        JDK8中接口可以定义静态方法,默认方法

                1.接口中中定义的静态方法只能通过接口来调用。
                2.通过实现类的对象,可以调用接口中的默认方法 。

                3. 类优先原则--->如果子类(实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中同名同参数的方法。

                4.接口冲突--->如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法 ,那么在实现类没有重写此方法的情况下,报错。这就需要我们必须重写此方法

                5.如何在子类中调用父类或接口中被重写的方法
                        method3();//调用自己定义的重写的方法
                        super.method3();//调用的是父类中声明的
                        CompareA.super.method3();//调用接口中的默认方法

//JDK8中可以定义静态方法,默认方法
interface CompareA{
	//静态方法
	public static void method1() {
		System.out.println("CompareA.北京");
	}
	//默认方法
	public default void method2() {
		System.out.println("CompareA.上海");
	}
	default void method3() {
		System.out.println("CompareA.成都");
	}
}
interface CompareB{
	public default void method3() {
		System.out.println("CompareB.成都");
	}
}
class Superclass{
	public void method3() {
		System.out.println("super.成都");
	}
}
class Subclass extends Superclass implements CompareA,CompareB{
	public void method2() {//重写
		System.out.println("重写.上海");
	}
	public void method3() {
		System.out.println("重写.成都");
	}
	
	public void mymethod() {
//      知识点5.如何在子类中调用父类或接口中被重写的方法
		method3();//调用自己定义的重写的方法
		super.method3();//调用的是父类中声明的
		CompareA.super.method3();//调用接口中的默认方法
		CompareB.super.method3();
	}
}
class SubclassTest{
	public static void main(String[] args) {
		Subclass s = new Subclass();
//		s.method1();
//		知识点1.接口中中定义的静态方法,只能通过接口来调用
//		Subclass.method1();
		CompareA.method1();
//		知识点2.通过实现类的对象,可以调用接口中的默认方法
		s.method2();
//		知识点3.类优先原则--->
//		如果子类(实现类)继承的父类和实现的接口中声明了同名同参数的方法,
//		那么子类在没有重写此方法的情况下,默认调用的是父类中同名同参数的方法
		s.method3();
//		知识点4.接口冲突--->
//		如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法 ,
//		那么在实现类没有重写此方法的情况下,报错。
//		这就需要我们必须重写此方法。
		s.method3();
	}
}

25类的成员之五:内部类

        概念 

f080f9c9658f429e8c25692833a7fa11.png

 成员内部类

        一方面,作为外部类的成员

                >调用外部类的结构(静态不能调用非静态...)

                >可以用static修饰

                >可以使用四种权限修饰符修饰

        另一方面,作为一个类

                >类中可以定义属性,方法,构造器

                >可以用final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承。

                >可以被abstract修饰

        关注如下三个问题

                1.如何实例化成员内部类的对象

		//创建Innerclass1的实例(静态成员内部类)
		Exclass.Innerclass1 in1 = new Exclass.Innerclass1();
		in1.method1();
		//创建Innerclass2的实例(非静态成员内部类)
		Exclass ex2 = new Exclass();
		Exclass.Innerclass2 in2 = ex2.new Innerclass2();
		in2.method2();

                2.如何在成员内部类中区分调用外部类的结构

class Exclass{
    String name;
	int age;

	 class Innerclass2{
		String name;
		public void method2() 
			
		Exclass.this.method3();//调用外部类的方法
		System.out.println(age);

		public void display(String name)
        {
		    System.out.println(name);//方法的形参
		    System.out.println(this.name);//内部类的属性
		    System.out.println(Exclass.this.name);//外部类的属性
        }
	}
}

                3.开发中局部内部类的使用(InnerclassTest)

public class InnerclassTest1 {
//	开发中很少见
	public void method() {
		class AA{
			
		}
	}
//	返回一个实现了Comparable接口的类的对象
	public Comparable getComparable() {//Comparable:要返回的类型
		//创建一个实现了Comparable接口的类:局部内部类
		//方法一:创建了一个有名实现类的匿名对象
//		class MyComparable implements Comparable{
//
//			@Override
//			public int compareTo(Object o) {
//				// TODO Auto-generated method stub
//				return 0;
//			}
//		}
//		return new MyComparable();
		//方法二:创建了一个匿名实现类的匿名对象
		return new Comparable() {

			@Override
			public int compareTo(Object o) {
				// TODO Auto-generated method stub
				return 0;
			}
			
		}
	}
}

 END

异常处理 

1异常概述与异常体系结构

cbb660bac1c14ff593d276ec3f822b09.png

        Error 

	public static void main(String[] args) {
//		1.栈溢出:java.lang.Stack OverflowOverflowError
		main(args);
//		2.堆溢出:java.lang.OutOfMemoryError
		Integer[] arr = new Integer[1024*1024*1024];
	}

         Exception

1dc21cc2504c42239a73822c57410bcf.png

65faef1aa43b40da8c1d9b9f86c628b0.png

 2常见异常

public class ExceptionTest {
//	运行时异常
//	(1)空指针异常:java.lang.NullPointerException
	@Test
	public void test1() {
		int[] arr = null;
		System.out.println(arr[3]);
		
		String str = "abc";
		//System.out.println(str.charAt(0));//✔
		str = null;
		System.out.println(str.charAt(0));//✘
	}
//	(2)数组下标越界:java.lang.ArrayIndexOutOfBoundsException
	@Test
	public void test2() {
		int[] arr = new int[3];
		System.out.println(arr[3]);
		
//		StringIndexOutOfBoundsException
		String str = "abc";
		System.out.println(str.charAt(3));
	}
//	(3)类型转换异常:java.lang.ClassCastException
	@Test
	public void test3() {
		//String str = new Date();//不算该类型
		Object obj = new Date();
		String str = (String)obj;
	}
//	(4)数字格式化异常:java.lang.NumberFormatException
	@Test
	public void test4() {
		String str = "123";//✔
		str = "abc";//✘
		int num = Integer.parseInt(str);
	}
//	(5)接收非法输入异常:java.util.InputMismatchException
	@Test
	public void test5() {
		Scanner in = new Scanner(System.in);
		int score = in.nextInt();//输入的时候不是数字出错
		System.out.println(score);
		
		in.close();
	}
//	(6)算术异常:java.lang.ArithmeticException
	@Test
	public void test6() {
		int a = 10;
		int b = 0;
		System.out.println(a/b);//1.除0
	}
//	*******************************
//	编译时异常
//	(1)
	@Test
	public void test7() {
		File file = new File("hello.txt");
		FileInputStream fis = new FileInputStream(file);
		
		int data = fis.read();
		while(data!=-1)
		{
			System.out.println((char)data);
			data = fis.read();
			
			fis.close();
		}
	}
}

 

3异常处理机制一:try-catch-finally

        抓抛模型

                过程一:“抛”:程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。并将此对象抛出。

                                         一旦抛出对象以后,其后的代码就不再执行。

                        关于异常对象的产生:1.系统自动生成的异常对象

                                                             2.手动的生成一个异常对象,并抛出(throw)

                过程二:“抓” :可以理解我异常的处理方式:1.try-catch-finally 2.throws

                                                try{

                                                        //可能出现异常的代码

                                                } catch(异常类型1 变量名1){

                                                        //处理异常的方式1

                                                }

                                                catch(异常类型2 变量名2){

                                                        //处理异常的方式2

                                                }

                                                ......

                                                finally{

                                                        //一定会执行的代码

                                                }

        注意事项

                1.finally是可选的

                2.使用try将可能出现的异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常的对象,根据此对象的类型,去catch中匹配。

                3.一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常处理,一旦处理完成,就跳出当前的try-catch结构(无finally情况),继续执行其后的代码。

                4.catch中的异常类型如果没有子父类关系,则谁声明在下无所谓。catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面,否则会报错

                 5.常用异常处理方式:1.String getMessage();

                                                     2.printStackTrace();

                6.在try结构中声明的变量,再出了try之后,就不能在调用

                7.体会:使用try-catch-finally解决编译时异常,使得程序在编译时不再报错,但是运行时扔可能报错,相当于我们使用try-catch-finally讲一个编译时可能出现的异常,延迟到运行时出现。

                             开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。针对于编译时异常,我们说一定要考虑异常的处理

                finally

                8.finally中声明的是一定会被执行的代码,即使catch中又出现异常了,try中有return语句,catch中有return语句等情况。

                9.什么时候用finally:像数据库连接,输入输出流,网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动的进行资源的释放,此时的资源释放,就需要声明在finally中。

                10.try-catch-finally结构是可以嵌套·的 

代码见ExceptionTest

4异常处理机制二:throws

         格式

        1.throws + 异常类型   写在方法的声明处,指明此方法执行时,可能会抛出的异常类

       2. 一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码就不再执行。

        体会

                try-catch-finally才是真正的将异常处理掉了;

                throws只是将异常抛给了方法的调用者,并没有真正的将异常处理掉。

public class ExceptionTest2 {
	public static void main(String[] args) {
		try {
			method2();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void method2() throws IOException{
		method1();
	}
	public static void method1()throws FileNotFoundException,IOException {
		File file = new File("hello.txt");
		FileInputStream fis = new FileInputStream(file);
		
		int data = fis.read();
		while(data!=-1)
		{
			System.out.println((char)data);
			data = fis.read();
			
			fis.close();
		}
	}
}

ExceptionTest2 

        方法重写规则之一

                子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型 

​
public class OverrideTest {
	public static void main(String[] args) {
		display(new Subclass1());
	}
	public static void display(Superclass1 s){
		try {
			s.method();
		} catch (IOException e) {//如果子类的方法抛出的异常值大于父类,在传入此方法时这就报错
			e.printStackTrace();
		}
	}
}
class Superclass1{
	public void method() throws IOException{
		
	}
}
class Subclass1 extends Superclass1{
	public void method1() throws FileNotFoundException{
		
	}
}

​

OverrideTest 

        开发中如何选择使用try-catch-finally 还是使用throws

        1.如果父类中被重写 的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally方式处理。

        2.在执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的,建议这几个方法使用throws的方式进行处理,而执行的方法a可以考虑使用try-catch-finally方式进行处理

5手动抛出异常:throw

public class ThrowTest {
	public static void main(String[] args) {
		Stu s = new Stu();
		try {
			s.regist(-1001);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(s);
	}
}
class Stu{
	private int id;
	public void regist(int id) throws Exception {
		if(id>0)
			this.id = id;
		else
//			System.out.println("您输入的数据非法!");
//			1.手动抛出异常对象
//			throw new RuntimeException("您输入的数据非法!");
//			2.运行时才能检测
//			throw new Exception();
//			3.自定义异常类
			throw new MyException("输入不能为负数");
	}
}

ThrowTest 

6用户自定义异常类

          如何自定义异常类

                  1.继承于现有的异常结构:RuntimeException、Exception
                  2.提供全局常量:serialVersionUID
                  3.提供重载的构造器 

/*
 * 如何自定义异常类
 * 1.继承于现有的异常结构:RuntimeException、Exception
 * 2.提供全局常量:serialVersionUID
 * 3.提供重载的构造器
 */
public class MyException extends RuntimeException{
	static final long serialVersionUID = -7034897190745766939L;
	
	public MyException() {
		
	}
	
	public MyException(String msg){
			super(msg);
		}
}

MyException 

c1291b5cfb8a498ea1ec581301f364c9.png Exercise9_10毁灭吧

 多线程

1.基本概念:程序,进程,线程

        概念 

                7153092e7d11497d94540b93a0119c76.png

        单核CPU和多核CPU 

                 82b774462054424ca14084d5369cb59e.png

        使用多线程的优点

                7bcb5dbf300b48c7911fd870e9492358.png

                解释:单核只能并发执行多线程(切换开销),没法并行执行多线程,所以导致做一个事情用2个线程比用一个线程时间更多

        何时需要多线程

                 799da7e7c40347aba483dad18199f1d4.png

2.线程的创建与使用

        6d48e122781f4da9b95f01522d3097d9.png

                Thread类中有关方法

4da93d29ea7240c7bc9cbc2be35213c2.png

7c49c5a73a7f44648185cd1ed2aee943.png

 代码见ThreadMethodTest

/*
测试Thread中常用方法:
1.start():启动当前线程,调用当前线程的run()
2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
3.currentThread():静态方法,返回执行当前代码的线程
4.getName():获取当前线程的名字
5.setName():设置当前线程的名字
6.yield():释放当前CPU的执行权
7.join():在线程a中调用线程b的join(),此时线程啊就进入阻塞状态,直到线程b执行完以后,线程a才结束阻塞状态
8.stop():强制结束当前方法(已过时)
9.sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒,在指定的millitime毫秒时间内,当前线程时阻塞状态
10.isAlive():判断线程还是否存在
 */
public class ThreadMethodTest {
    public static void main(String[] args) {
        HelloThread helloThread = new HelloThread("Thread_1");
        helloThread.start();
//       setName方式一: helloThread.setName("线程一");

//       给主线程命名
        Thread.currentThread().setName("主线程");

        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0)
                System.out.println(Thread.currentThread().getName() + ":" + i);
            if (i == 20) {
                try {
                    helloThread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(helloThread.isAlive());
    }
}
class HelloThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
            if (i % 20 == 0)
                this.yield();
        }
    }
    //   setName方式二:
    public HelloThread(String name) {
        super(name);
    }
}

 

        多线程的创建

                方式一:继承于Thread类
                        1.创建一个继承于Thread类的子类
                        2.重写Thread的run()方法
                        3.创建Thread类的子类的对象
                        4.通过此对象调用start()方法:

                                        作用: 1.启动当前线程
                                                  2.调用当前线程的run()方法 

                        注意:

                                bd6aef31bed84c6893f294aedf9dda6b.png 

 

代码见ThreadTest和ThreadDemo 

                方式二:实现Runnable接口

                        1.创建一个实现了Runnable接口的类
                        2.实现类去实现Runnable中的抽象方法:run()
                        3.创建实现类的对象
                        4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
                        5.通过Thread类的对象调用start()

                                        作用:1.启动线程

                                                   2.调用当前线程的run()--->调用了Runna类型的target的run()

  代码见ThreadTest2

区分这两种方法的代码:ThreadWindowsTest1和ThreadWindowsTest2 

        创建线程的两种方式的比较

                        开发中,优先选择实现Runnable接口的方式

                                原因: 实现的方式没有类的单继承性的局限性

                                            实现的方式更适合来处理多个线程有共享数据的情况

        联系:public class Thread implements Runnable。

        相同点: 两种方式都需要去重写run(),将线程要执行的逻辑声明在run()中。

        线程的调度 

                1646556167894cf6a77fe825e6cddf46.png

                25809e12171a47a5965a78ba32c24e32.png

  代码见ThreadMethodTest

 

3.线程的生命周期

58bf64a862824a6eac17372597a304de.png

 4d72ecc020434317a047984191526a5b.png

 

4.线程的同步

"C:\Users\姜九笙\Desktop\新建文件夹\1_课件\第2部分:Java高级编程\第2部分:Java高级编程\尚硅谷_宋红康_第8章_多线程\尚硅谷_宋红康_第8章_多线程.pdf" 

 代码笔记见ThreadWindowsTest1(同步代码块解决继承Thread类的线程安全问题)

                   ThreadWindowsTest2(同步代码块解决实现Runnable接口的线程安全问题)(主)

                   ThreadWindowsTest3(同步方法解决继承Thread类的线程安全问题)

                   ThreadWindowsTest4(同步方法解决实现Runnable接口的线程安全问题)

                   LockTest(Lock锁解决线程安全问题),LanHan,DeadlockTest

                bd1276c974594a148f6f8145a0f13aff.png 

                501fe4434f7c42eeab9b128b31c01012.png

                9efee6e1016c4a7580034c556063108f.png

                02d4c9e586374e3886c349a927fe30f1.png

                 3dd1be1af3594826bdb2e672abb36bfa.png

 

                cc2173b36fab4a2bb0e3f4813b55b8d2.png

 

5.线程的通信

代码笔记见ThreadCommunicationTest(主)

wait(),notify(),notifyAll() 

                  ThreadComCustomerTest(练习,经典)

6.JDK5.0新增线程创建方法

                3e4d6c516234433aaec5b4ece91d5e11.png

ThreadCallableTest(实现Callable接口)

                8c398c6a633c4d79977ff0043f615e8b.png

                11262f2bd53b44c0bc266e0892ae22fd.png

 

ThreadPoolTest(线程池)

集合 

1Java集合框架概述

 

2Collection接口方法

 

3Iterator迭代器接口

 

4Collection子接口一:List

 

5Collection子接口二:Set

6Map接口

7Collections工具类

 
 

常用类 (详见PPT)

1 字符串相关的类

        String类

f21bc7bf38194c13b64051e63c36aaa7.png

3c39cdc30e894abca68af39c9040826a.png

b2ca324f61074f478d28995cfa8a6654.png

8ce96380a48e41668f7c7ef5606ae4f7.png

77772c2dc2524a58b625c20641bbe406.png

        String的常用方法

                148fcd2c7d9d4ef5bc0cd609a559015f.png

                e94b2b8c30b6472cabf11ab9fde8fb7b.png                         

                b96503d1fd26490cb5f28b89615b9c34.png

        String与其他类进行转换

                de37081fe9ad474ea8f3015da1e8381c.png

                77ebc28ccf3641e9aff59cc86de73c2b.png 

                 80762fab233044898695ab9e360a290d.png

 

        StringBuffer

 

 

        StringBuilder

 

2JDK8之前的日期时间API

        System静态方法

        Date类

        Calendar类

        SimpleDateFormat类

3JDK8中日期时间API

        LocalDate,LocalTime,LocalDateTime

        Instant

        DateTimeFormatter

        其他类

4Java比较器

        Comparable接口

        Comparator接口

5System类

6Math类

7BigInteger与BigDecimal

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值