• 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day01~day10)(2015年11月17日20:47:22)


    本笔记是个人笔记+摘录笔记相结合,非完全原创

     

    day01

    win 7系统打开DOS有趣方法:按住shift+右键,单击“在此处打开命令窗口”(注意:在此处可以是任何的文件夹,不一定是桌面)

    用DOS删除的文件不可以在回收站恢复?!!

    常用DOS命令
    d: 回车 盘符切换
    dir(directory):列出当前目录下的文件以及文件夹
    md (make directory) : 创建目录(创建文件夹)
    rd (remove directory): 删除目录(删除文件夹,注意:前提是文件夹必须是空的!!)
    如果想删除不是空的文件夹(比如删除aaaaa文件夹),可以用命令 rd /s aaaaa(会有删除提示)或者rd /s /q aaaaa(静默删除)
    cd (change directory)改变指定目录(进入指定目录)
    cd.. : 退回到上一级目录
    cd: 退回到根目录
    del (delete): 删除文件,删除一堆后缀名一样的文件*.txt
    exit : 退出dos命令行
    cls : (clear screen)清屏

     

     第一个程序:HelloWorld案例(掌握)

     

     1  class HelloWorld {
     2  
     3 
     4   public static void main(String[] args) {
     5  
     6 
     7    System.out.println("HelloWorld");
     8  
     9 
    10   }
    11  
    12 
    13  }

     

     

     (1)程序解释:

     

      A:Java程序的最基本单位是类,所以我们要定义一个类。

     

       格式:class 类名

     

       举例:class HelloWorld

     

      B:在类中写内容的时候,用大括号括起来。

     

      C:Java程序要想执行,必须有main方法。

     

       格式:public static void main(String[] args)

     

      D:要指向那些东西呢,也用大括号括起来。

     

      E:你要做什么呢?今天我们仅仅做了一个简单的输出

     

       格式:System.out.println("HelloWorld");

     

       注意:""里面的内容是可以改动的。

     

     

     

     (2)Java程序的开发执行流程:

     

      A:编写java源程序(.java)

     

      B:通过javac命令编译生成.class文件

     

      C:通过java命令运行.class文件

     

     

     

    常见的问题(掌握)

     

     (1)扩展名被隐藏

     

      如何找到:工具--文件夹选项--查看--去除隐藏扩展名的那个勾勾

     

    (2)要求文件名称和类名一致。

     

      实际上不这样做也是可以的。

     

      但是,注意:

     

       javac后面跟的是文件名+扩展名

     

       java后面跟的类名不带扩展名

     

     (3)Java语言严格区分大小写,请注意。

     

       还有就是单词不要写错了。

     

     (4)见到非法字符: 65307肯定是中文问题。

     

        写程序要求标点符号必须全部是英文状态。

     

     (5)括号的配对问题。

     

      一般来说,括号都是成对出现的。

     

     (6)遇到

     

      在类 HelloWorld 中找不到主方法, 请将主方法定义为

     

      肯定是主方法的格式问题。

     

     

     

    path环境变量

     

     path环境变量的作用

     

      保证javac命令可以在任意目录下运行。

     

      同理可以配置qq等

     

     

     

     

     

     

     

    day2

     

    1.java关键字--组成关键字的字母全部小写

     

    注意:goto和const作为保留字存在,目前并不使用(在JDK的新版本中可能提升为关键字)

     

     

     

    2.demo:案例,演示

     

     

     

    3.Java标识符

     

    可以是

     

     英文大小写字母

     

     数字字符

     

     $和_

     

     

     

     注意:

     

     A.不能以数字开头

     

     B.不能是Java中的关键字

     

     C.Java语言严格区分大小写

     

     

     

     

     

    4.常见的命名规则(重点):见名知意

     

      举例:我要定义一个学生类

     

       class Student {}

     

       class S{}

     

       

     

      :其实就是文件夹,用于把相同的类名进行区分

     

       全部小写

     

      

     

       单级:liuyi

     

       多级:cn.itcast(解析:cn是一个文件夹,itcast也是一个文件夹,cn文件夹里包含有itcast文件夹)

     

        cn

     

         itcast

     

         

     

      类或者接口:

     

       一个单词:单词的首字母必须大写

     

        举例:Student,Dog

     

       多个单词:每个单词的首字母必须大写

     

        举例:HelloWorld,StudentName

     

       

     

      方法或者变量

     

       一个单词:单词的首字母小写

     

        举例:main,age

     

       多个单词:从第二个单词开始,每个单词的首字母大写

     

        举例:studentAge,showAllNames()

     

       

     

      常量:

     

       一个单词:全部大写

     

        举例:PI

     

       多个单词:每个字母都大写,用_隔开

     

        举例:STUDENT_MAX_AGE

     

     

     

     

     

    5.Java中注释的分类及格式

     

      单行注释://

     

      多行注释:/星 星/

     

       注意:多行不可以嵌套使用,而单行是可以的

     

      文档注释:被javadoc工具解析生成一个说明书

     

     

     

    用注释写的一个Java案例

     

    ===========================华丽的分割线=========================================

     

    /*

     

     需求:我准备写一个java程序,把“HelloWorld”这句话输出在控制台

     

     

     

     分析:A:要写一个java程序,必须定义类

     

       B:把数据能够输出,说明我们的程序是可以独立运行的,而程序要独立运行,必须定义main方法

     

       C:把数据输出在控制台,必须使用输出语句

     

       

     

     实现:

     

       A:java语言提供了一个关键字:class用来定义类,后面跟的是类名

     

       B:main方法的格式是固定的:

     

       public static void main(String[] args) {
     
       }

     

       C:输出语句的格式是固定的:

     

       System.out.println("HelloWorld");

     

       "HelloWorld"这个内容是可以改变的

     

     

     

    */

     

     

     

    //这是我的HelloWorld案例

     

    class HelloWorld {

     

     /*

     

      为了程序能够独立运行,定义main方法

     

      main方法是程序的入口

     

      被jvm自动调用

     

     */

     

     public static void main(String[] args) {

     

      //为了把数据显示在控制台,我们就使用了输出语句

     

      System.out.println("HelloWorld");

     

     }

     

    }

     

    ===========================华丽的分割线=============================================

     

     

     

     

     

    6.常量:

     

      在程序执行过程中,其值不发生改变的量。

     

     分类:

     

      A:字面值常量

     

      B:自定义常量(后面讲)

     

     字面值常量

     

      A:字符串常量 用双引号括起来的内容。

     

      B:整数常量 所有的整数

     

       举例:100, 200

     

      C:小数常量 所有的小数

     

       举例:10.23,110.11

     

      D:字符常量 用单引号括起来的内容

     

       举例:‘a’,‘A’,‘0’

     

       错误的:‘ab’

     

      E:布尔常量 比较特殊

     

       举例:true,false

     

      F:空常量 后面讲

     

       举例:null

     

     

     

    7.Java进制

     

     Java针对整数常量提供了4种表现形式

     

     二进制(jdk7以后有)

     

     八进制

     

     十进制

     

     十六进制

     

     

     

     

     

    8.快速的进制转换法

     

     8421码,是bcd码一种。

     

     它表达的意思是每一个二进制位上的数据对应一个固定的值,

     

     只需要把对应的1位置的数据值给相加,即可得到该二进制对应的十进制的值

     

     

     

     二进制 1 1 1 1 1 1 1 1

     

     

     

     十进制 128 64 32 16 8 4 2 1

     

     

     

     

     

     例  

     

     二进制到十进制的转换

     

     1010100 = 64 + 16 + 4 = 84;

     

     

     

     十进制到二进制的转换

     

     100 = 0b1100100(对照着看,首先100<128,所以第八位为0;然后100>64,第七位为1;接着,100-64=36,36>32,所以第六位为1;然后,36-32=4,4<16,所以第五位为0;然后,4<8,第四位为0;然后,4=4,所以第三位为1;

     

     然后,0<2,第二位为0;然后0<1,第一位为0,总的来说是01100100,去掉首位的0就是1100100,再规范化表示为0b1100100)
     
     
     

    9.原码反码补码
    原码:
    正数的原码最高位是0;
    负数的原码最高位是1;
    其他的是数值位。
    符号位 数值位
    +7 0 0000111
    -7 1 0000111

    反码:
    正数的反码与原码相同。
    负数的反码与原码是符号不变,数值位取反(0变1,1变0)

    +7 0 0000111
    -7 1 1111000

    补码:
    正数的补码与原码相同
    负数的补码是在反码的基础上加1.

    +7 0 0000111
    -7 1 1111001

     

    有符号数据表示法的练习
    A:已知某数X的原码为10110100B,试求X的补码和反码。

    符号位 数值位

    原码: 1 0110100

    反码: 1 1001011

    补码: 1 1001100

    B:已知某数X的补码11101110B,试求其原码。

    符号位 数值位

    补码: 1 1101110

    反码: 1 1101101

    原码: 1 0010010


    10.数据类型:Java是一种强类型的语言,针对每一种数据都定义了明确的数据类型。

    数据类型分类:
    A:基本数据类型
    B:引用数据类型(类,接口,数值)

    基本数据类型:4类8种
    A:整数 占用字节数
    byte 1
    short 2
    int 4
    long 8

    B:浮点数
    float 4
    double 8

    C:字符
    char 2
    D:布尔
    boolean 1

    注意:
    整数默认是int类型
    浮点数默认是double类型。

    长整型后缀用L或者l标记。建议使用L。
    例如
    在Java中,

    1 long j = 10000000000;
    2 System.out.println(j);

     


    编译时会报错 错误: 过大的整数: 10000000000,因为整数(这里是10000000000)默认是int类型
    解决办法 long j = 10000000000L;


    单精度浮点数用F或者f标记。建议使用F。
    例如
    在Java中,
    float f = 12.345;
    System.out.println(f);
    编译时会报错 错误: 不兼容的类型: 从double转换到float可能会有损失
    解决办法 float f = 12.345F;

    11.数据类型转换
    默认转换(从小到大的转换)
    A:byte,short,char—int—long—float—double
    B:byte,short,char相互之间不转换,他们参与运算首先转换为int类型
    举例
    =================================================================

    1 byte a = 3;
    2 
    3 int b = 4;
    4 
    5 byte c = a + b;//有问题
    6 
    7 int d = a + b;//没有问题

     

     

    =================================================================
    上述 byte c = a + b;//有问题
    如何解决?用强制类型转换


    12.强制转换:
    从大的数据类型到小的数据类型。

    格式:
    目标数据类型 变量 = (目标数据类型) (被转换的数据);

    注意:
    不要随意的去使用强制转换,因为它隐含了精度损失问题。
    那么,
    //用强制类型转换改进
    byte c = (byte) (a + b);
    System.out.println(c);

    13.思考题:看看下面两个定义有没有区别呢?
    float f1 = (float)12.345;
    float f2 = 12.345f;

    f1其实是通过一个double类型转换过来的。
    而f2本身就是一个float类型。(建议用f2的写法)

    14.面试题
    A面试题:
    byte b1=3,b2=4,b;
    b=b1+b2;
    b=3+4;
    哪句是编译失败的呢?为什么呢?

     


    答:b = b1 + b2;是有问题的。
    因为变量相加,会首先看类型问题,最终把结果赋值的也会考虑类型问题。
    常量相加,首先做加法,然后看结果是否在赋值的数据类型范围内,如果不是,才报错。

    也就是说。b = b1 + b2; -----这个是类型提升,所有有问题。b1 + b2首先整体提升为int类型(byte,short,char相互之间不转换,他们参与运算首先转换为int类型),int类型的(b1+b2)赋值给byte类型的b,所以有损失精度的错误。

    b = 3 + 4; //常量,先把结果计算出来,然后看是否在byte的范围内,如果在就不报错。也就是说,编译器把3+4看做一个常量而不是变量的加法运算。所以不报错

    15.强制转换数据溢出后的结果怎么算(一个实例)

    byte b = 130;有没有问题?如果我想让赋值正确,可以怎么做?结果是多少呢?

    //我们可以使用强制类型转换
    byte b = (byte) 130;

    //结果是多少呢?
    System.out.println(b);

    分析过程:
    我们要想知道结果是什么,就应该知道是如何进行计算的。
    而我们又知道计算机中数据的运算都是补码进行的。
    而要得到补码,首先要计算出数据的二进制。

    A:获取130这个数据的二进制。
    00000000 00000000 00000000 10000010
    这是130的原码,也是反码,还是补码。
    B:做截取操作,截成byte类型的了。
    10000010
    这个结果是补码。
    C:已知补码求原码。(注意不要漏掉这一步,因为内存中操作的是补码,而我们看到的是补码,所以还要转换成原码)
    符号位 数值位
    补码: 1 0000010

    反码: 1 0000001

    原码: 1 1111110
    16.
    //直接输出一个字符
    System.out.println('a'); //输出a
    //输出一个字符和一个整数做加法
    System.out.println('a'+1); //输出98

    ASCII码表。
    记住三个值:
    'a' 97
    'A' 65
    '0' 48注意

    17.字符串参与运算

    1 System.out.println("hello"+'a'+1); //输出helloa1,hello优先与‘a’结合
    2 System.out.println('a'+1+"hello"); //输出98hello,‘a’优先与1结合,形成98再与hello结合
    3 
    4 System.out.println("5+5="+5+5); //输出5+5=55,字符串与数字5先结合
    5 System.out.println(5+5+"=5+5"); //输出10=5+5,5+5优先形成10,再与字符串结合

     

     

     

    补:‘a’+1有类型提升???!

     

     

     

    day3

     

    1.在定义Long或者Float类型变量的时候,要加L或者f。

     

      整数默认是int类型,浮点数默认是double。

     

     

     

      byte,short在定义的时候,他们接收的其实是一个int类型的值。

     

      这个是自己做了一个数据检测的,如果不再它们的范围内,就报错。

     

      float表示的数据范围比long的范围要大

     

      long:2^63-1

     

      float:3.4*10^38 > 2*10^38 > 2*8^38 = 2*2^3^38 = 2*2^114 > 2^63-1

     

     

     

    2.面试题:Java语言中的字符char可以存储一个中文汉字吗?为什么呢?

     

     可以。因为java语言中的字符占用两个字节。(Java中char占两个字节,C语言中char占一个字节)

     

     

     

     Java语言采用的是Unicode编码。

     

    3.

     

     A:整数相除只能得到整数。如果想得到小数,必须把数据变化为浮点数类型

     

     B:/获取的是除法操作的商,%获取的是除法操作的余数

     

    =========================================================================

     

     System.out.println(x/y); //整数相除只能得到整数

     

     

     

      //我就想得到小数,该肿么办呢?

     

      //只需要把操作的数据中任意的一个数据变为浮点数

     

      System.out.println(x*1.0/y);

     

     

     

      //%的应用

     

      System.out.println(x%y); //得到的是余数

     

    ==========================================================================

     

    4.++,--运算符的使用

     

    //参与运算使用

     

      
     1  int a = 3;
     2    int b = 4;
     3 
     4    int c = a++;
     5 
     6    int d = b--;
     7 
     8    System.out.println("a:"+a); //输出为4
     9 
    10    System.out.println("b:"+b); //输出为3
    11 
    12    System.out.println("c:"+c); //输出为3
    13 
    14    System.out.println("d:"+d); //输出为4

     

     

     

     

    5.一个面试题
    面试题:
    short s=1;s = s+1;

    short s=1;s+=1;
    上面两个代码有没有问题,如果有,那里有问题。

     1 class OperatorTest {
     2 public static void main(String[] args) {
     3 //short s = 1;
     4 //s = s + 1;
     5 //System.out.println(s);
     6 
     7 short s = 1;
     8 s += 1; //好像是 s = s + 1;
     9 System.out.println(s);
    10 }
    11 }

     

    为什么第二个木有问题呢?
    扩展的赋值运算符其实隐含了一个强制类型转换。

    s += 1;
    不是等价于 s = s + 1;
    而是等价于 s = (s的数据类型)(s + 1);
    (个人理解)也就是说,s = s + 1中的s + 1包含了加法运算,short类型出现了提升(提升为int类型)
    而s+=1本身隐含了强制的类型转换


    6.逻辑运算符:
    &,|,^,!
    &&,||

    特点:
    逻辑运算符一般用于连接boolean类型的表达式或者值。

    表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子。
    算术表达式:a + b
    比较表达式:a == b

    结论:
    &逻辑与:有false则false。
    |逻辑或:有true则true。
    ^逻辑异或:相同为false,不同为true。
    举例:情侣关系。男男,男女,女男,女女
    !逻辑非:非false则true,非true则false。
    特点:偶数个不改变本身。

    例如
    int a = 3;
    int b = 4;
    int c = 5;

    //&逻辑与

    1 System.out.println((a > b) & (a > c)); //false & false = false
    2 System.out.println((a > b) & (a < c)); //false & true = false
    3 System.out.println((a < b) & (a > c)); //true & false = false
    4 System.out.println((a < b) & (a < c)); //true & true = true

     

    7.Java中&&与&

    &&和&的区别? 同理||和|的区别?
    A:最终结果一样。
    B:&&具有短路效果。左边是false,右边不执行。

    开发中常用的逻辑运算符:
    &&,||,!
    示例

    1 //boolean b1 = ((x++ == 3) & (y++ == 4));
    2 //boolean b1 = ((x++ == 3) && (y++ == 4));
    3 //boolean b1 = ((++x == 3) & (y++ == 4));
    4 boolean b1 = ((++x == 3) && (y++ == 4));
    5 System.out.println("x:"+x);
    6 System.out.println("y:"+y);
    7 System.out.println(b1);

     

     

     

    8.位运算符:
    &,|,^,~
    <<,>>,>>>

    注意:
    要做位运算,首先要把数据转换为二进制。
    例子

     

    int a = 3;
    int b = 4;

    System.out.println(3 & 4);
    System.out.println(3 | 4);
    System.out.println(3 ^ 4);
    System.out.println(~3);

     

    分析:因为是位运算,所以我们必须先把数据换算成二进制。

    3的二进制:11
    00000000 00000000 00000000 00000011
    4的二进制:100
    00000000 00000000 00000000 00000100

    &位与运算:有0则0。
    00000000 00000000 00000000 00000011
    &00000000 00000000 00000000 00000100
    -----------------------------------
    00000000 00000000 00000000 00000000
    结果是:0

    |位或运算:有1则1。
    00000000 00000000 00000000 00000011
    |00000000 00000000 00000000 00000100
    -----------------------------------
    00000000 00000000 00000000 00000111
    结果是:7

    ^位异或运算:相同则0,不同则1。
    00000000 00000000 00000000 00000011
    &00000000 00000000 00000000 00000100
    -----------------------------------
    00000000 00000000 00000000 00000111
    结果是:7

    ~按位取反运算符:0变1,1变0
    00000000 00000000 00000000 00000011
    ~11111111 11111111 11111111 11111100 (补码)

    补码:11111111 11111111 11111111 11111100
    反码:11111111 11111111 11111111 11111011
    原码:10000000 00000000 00000000 00000100
    结果是:-4

     

    9.^的特点:一个数据位异或两次,该数本身不变。(^指的是异或运算符)
    例如
    int a = 10;
    int b = 20;

    System.out.println(a ^ b ^ b);//10
    System.out.println(a ^ b ^ a);//20
    10.一道面试题:
    请自己实现两个整数变量的交换(默认int类型.)
    例如
    int a = 10;
    int b = 20;
    System.out.println("a:"+a+",b:"+b);

     

     

     

     

     


    方式1:使用第三方变量(开发中用的)
    int c = a;
    a = b;
    b = c;
    System.out.println("a:"+a+",b:"+b);
    System.out.println("------------");

    方式2:用位异或实现(面试用)
    左边:a,b,a
    右边:a ^ b

    a = a ^ b;
    b = a ^ b; //a ^ b ^ b = a
    a = a ^ b; //a ^ b ^ a = b
    System.out.println("a:"+a+",b:"+b);

    方式3:用变量相加的做法

    a = a + b; //a=30
    b = a - b; //b=10
    a = a - b; //a=20
    System.out.println("a:"+a+",b:"+b);

    方式4:一句话搞定
    b = (a+b) - (a=b); //b=30-20=10,a=20
    System.out.println("a:"+a+",b:"+b);

    11.<<:左移 左边最高位丢弃,右边补齐0
    >>:右移 最高位是0,左边补齐0;最高为是1,左边补齐1
    >>>:无符号右移 无论最高位是0还是1,左边补齐0

     

     

     

    //<< 把<<左边的数据乘以2的移动次幂
    System.out.println(3 << 2); //3*2^2 = 3*4 = 12;

    //>> 把>>左边的数据除以2的移动次幂
    System.out.println(24 >> 2); //24 / 2^2 = 24 / 4 = 6
    System.out.println(24 >>> 2);

    System.out.println(-24 >> 2);
    System.out.println(-24 >>> 2);

     


    分析
    计算出3的二进制:11
    00000000 00000000 00000000 00000011
    (00)000000 00000000 00000000 0000001100

    >>的移动:
    计算出24的二进制:11000
    原码:10000000 00000000 00000000 00011000
    反码:11111111 11111111 11111111 11100111
    补码:11111111 11111111 11111111 11101000

    11111111 11111111 11111111 11101000
    1111111111 11111111 11111111 111010(00) 补码

    补码:1111111111 11111111 11111111 111010
    反码:1111111111 11111111 11111111 111001
    原码:1000000000 00000000 00000000 000110

    结果:-6

    >>>的移动:
    计算出24的二进制:11000
    原码:10000000 00000000 00000000 00011000
    反码:11111111 11111111 11111111 11100111
    补码:11111111 11111111 11111111 11101000

    11111111 11111111 11111111 11101000
    0011111111 11111111 11111111 111010(00)

    结果:
    update 2015年9月9日00:23:42

     

    12.&&:结果和&是一样的,只不过有短路效果。左边是false,右边不执行。
    ||:结果和|是一样的,只不过有短路效果。左边是true,右边不执行。

     

    Day 4
    1.switch:表示这是switch选择结构
    表达式:这个地方的取值是有限定的
    byte,short,int,char
    JDK5以后可以是枚举
    JDK7以后可以是字符串

     

    面试题
    byte可以作为switch的表达式吗?
    long可以作为switch的表达式吗?
    String可以作为switch的表达式吗?

     

    答:byte可以,long不可以,String在jdk7后可以

     

    2.switch要注意break问题
    例如

     

    int a = 2;
    int b = 3;
    switch(a)
    {
    default:
    b++;
    case 3:
    b++;
    case 4:
    b++;
    }
    switch语句只在遇到break才能停止,否则会一直执行下去

    3.if语句和switch语句的区别?
    if语句:
    A:针对结果是boolean类型的判断
    B:针对一个范围的判断
    C:针对几个常量值的判断

    switch语句:
    针对几个常量值的判断

     

     

    4.break
    break:中断的意思
    使用场景:
    A:switch语句中
    B:循环语句中。
    (循环语句中加入了if判断的情况)
    注意:离开上面的两个场景,无意义。

    如何使用呢?
    A:跳出单层循环
    B:跳出多层循环
    要想实现这个效果,就必须知道一个东西。带标签的语句。
    格式:
    标签名: 语句
    带标签的break语句相当于goto语句
    例子:

     1 //跳出单层循环
     2 for(int x=0; x<10; x++) {
     3   if(x == 3) {
     4   break;
     5   }
     6   System.out.println("HelloWorld");
     7 }
     8 
     9 //跳出多层循环
    10 wc:for(int x=0; x<3; x++) {
    11 nc:for(int y=0; y<4; y++) {
    12     if(y == 2) {
    13     //break nc;
    14     break wc;
    15     }
    16     System.out.print("*");
    17   }
    18   System.out.println();
    19 }
    20 
    21  

     

    break wc;语句跳出两个for循环,而普通的break语句只能跳出内层单循环。

     

     

    5.return:返回
    A:用于结束方法的;
    B:一旦遇到return,程序就不会在继续往后执行。

     

    day5
    1.方法
     方法就是完成特定功能的代码块
     在很多语言里面都有函数的定义
     函数在Java中被称为方法
     参数:
      实际参数:就是实际参与运算的。
      形式参数;就是方法定义上的,用于接收实际参数的。
    2.方法调用
    例子
    public static void main(String[] args) {
      int x = 10;
      int y = 20;
     
      //方式1:单独调用
      //sum(x,y);
     
      //方式2:输出调用
      //System.out.println(sum(x,y));
      //System.out.println(30);
     
      //方式3:赋值调用
      int result = sum(x,y);
      //result在这里可以进行操作
      System.out.println(result);
     }
     
     
     public static int sum(int a,int b) {
       return a + b;
     }
    3.方法重载
    实例
     1 /*
     2  需求:求两个数的和
     3 */
     4 class  FunctionDemo4
     5 {
     6  public static void main(String[] args)
     7  {
     8   //jvm会根据不同的参数去调用不同的功能
     9   System.out.println(sum(10,20));
    10   System.out.println(sum(10,20,30));
    11   System.out.println(sum(10,20,30,40));
    12   System.out.println(sum(10.5f,20));
    13  }
    14  //需求1:求两个数的和
    15  public static int sum(int a, int b)
    16  {
    17   System.out.println("int");
    18   return a + b;
    19  }
    20  
    21  //需求2:求三个数的和
    22  public static int sum(int a, int b, int c)
    23  {
    24   return a + b + c;
    25  }
    26  
    27  //需求3:求四个数的和
    28  public static int sum(int a, int b, int c, int d)
    29  {
    30   return a + b + c + d;
    31  }
    32  public  static float sum(float a,float b)
    33  {
    34   System.out.println("float");
    35   return a + b + c + d;
    36  }
    37 }

     

     
    方法重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
    方法重载特点:
    与返回值类型无关,只看方法名和参数列表
    在调用时,虚拟机通过参数列表的不同来区分同名方法
    简言之:在同一个类中,方法名相同,参数列表不同,与返回值类型无关。
     参数列表不同:
     A:参数个数不同
     B:参数类型不同
     
    4.数组
    数组:存储同一种数据类型的多个元素的容器。

    定义格式:
    A:数据类型[] 数组名;
    B:数据类型 数组名[];

    举例:
    A:int[] a; 定义一个int类型的数组a变量
    B:int a[]; 定义一个int类型的a数组变量
    推荐使用第一种格式

    对数组进行初始化
    a:动态初始化 只指定长度,由系统给出初始化值
    b:静态初始化 给出初始化值,由系统决定长度

    动态初始化的格式:
    数据类型[] 数组名 = new 数据类型[数组长度];

    举例:
    int[] arr = new int[3];

    如何获取数组中的元素呢?
    通过:
    数组名[索引]
    索引其实就是每个元素的编号,从0开始,最大索引是数组的长度-1。
    例子
    int[] arr = new int[3];
    //用数组名和编号的配合就可以获取数组中的指定编号的元素。这个编号的专业叫法:索引
    //通过数组名访问数据的格式是:数组名[索引];
    System.out.println(arr); //[I@175078b 地址值。
    System.out.println(arr[0]);//0
    System.out.println(arr[1]);//0
    System.out.println(arr[2]);//0

     


    数组的静态初始化:
    格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
    简化格式:
    数据类型[] 数组名 = {元素1,元素2,…};

    举例:
    int[] arr = new int[]{1,2,3};

    简化后:

    int[] arr = {1,2,3};

    注意事项:
    不要同时动态和静态进行。
    如下格式:
    int[] arr = new int[3]{1,2,3}; //错误
    5.数组操作的两个常见小问题:
    ArrayIndexOutOfBoundsException:数组索引越界异常
    原因:你访问了不存在的索引。
    例如
    int[] arr = {1,2,3};

    System.out.println(arr[3]);


    NullPointerException:空指针异常
    原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。
    例如
    //引用类型的常量:空常量 null
    arr = null;
    System.out.println(arr[0]);

    6.数组逆序
    例子
    逆序
    方式1:

    1 public static void reverse(int[] arr) {
    2             for(int x=0; x<arr.length/2; x++) {
    3                 int temp = arr[x];
    4                 arr[x] = arr[arr.length-1-x];
    5                 arr[arr.length-1-x] = temp;
    6             }
    7         }

     


    方式2:

    1 public static void reverse(int[] arr) {
    2             for(int start=0,end=arr.length-1; start<=end; start++,end--) {
    3                 int temp = arr[start];
    4                 arr[start] = arr[end];
    5                 arr[end] = temp;

     


    7.查找元素对应的索引值
    基本查找
    方式1:

    1 public static int getIndex(int[] arr,int value) {
    2             for(int x=0; x<arr.length; x++) {
    3                 if(arr[x] == value) {
    4                     return x;
    5                 }
    6             }
    7             
    8             return -1;
    9         }

     


    方式2(特别注意!):

    1 public static int getIndex(int[] arr,int value) {
    2             int index = -1;
    3         
    4             for(int x=0; x<arr.length; x++) {
    5                 if(arr[x] == value) {
    6                     index = x;
    7                     break;
    8                 }
    9             }

     

    day06
    1.二维数组
    就是元素为一维数组的一个数组。

    格式1
    数据类型[][] 变量名 = new 数据类型[m][n];
    m表示这个二维数组有多少个一维数组
    n表示每一个一维数组的元素个数

     

    举例:
    int[][] arr = new int[3][2];
    定义了一个二维数组arr
    这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2]
    每个一维数组有2个元素,可以通过arr[m][n]来获取
    表示获取第m+1个一维数组的第n+1个元素
    注意:
    A:以下格式也可以表示二维数组
    a:数据类型 数组名[][] = new 数据类型[m][n];
    b:数据类型[] 数组名[] = new 数据类型[m][n];
    一个实例
    public static void main(String[] args) {
    //定义一个二维数组
    int[][] arr = new int[3][2];
    //定义了一个二维数组arr
    //这个二维数组有3个一维数组的元素
    //每一个一维数组有2个元素
    //输出二维数组名称
    System.out.println(arr); //地址值 [[I@175078b
    //输出二维数组的第一个元素一维数组的名称
    System.out.println(arr[0]); //地址值 [I@42552c
    System.out.println(arr[1]); //地址值 [I@e5bbd6
    System.out.println(arr[2]); //地址值 [I@8ee016
    //输出二维数组的元素
    System.out.println(arr[0][0]); //0
    System.out.println(arr[0][1]); //0
    }

    二维数组格式1的内存图解

     

     

    格式2
    数据类型[][] 数组名 = new 数据类型[m][];

    m:表示这个二维数组有多少个一维数组。
    列数没有给出,可以动态的给。这一次是一个变化的列数。
    举例
    public static void main(String[] args) {
    //定义数组
    int[][] arr = new int[3][];

    System.out.println(arr); //[[I@175078b
    System.out.println(arr[0]); //null
    System.out.println(arr[1]); //null
    System.out.println(arr[2]); //null

    //动态的为每一个一维数组分配空间
    arr[0] = new int[2];
    arr[1] = new int[3];
    arr[2] = new int[1];

    System.out.println(arr[0]); //[I@42552c
    System.out.println(arr[1]); //[I@e5bbd6
    System.out.println(arr[2]); //[I@8ee016

    System.out.println(arr[0][0]); //0
    System.out.println(arr[0][1]); //0
    //ArrayIndexOutOfBoundsException
    //System.out.println(arr[0][2]); //错误

    arr[1][0] = 100;
    arr[1][2] = 200;
    }

     

     

     

    格式1,格式2属于动态初始化

     

    格式3

     

    基本格式:
    数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
    简化版格式:
    数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};

    举例:
    int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
    int[][] arr = {{1,2,3},{4,5},{6}};

     

    举例
    public static void main(String[] args) {
    //定义数组
    int[][] arr = {{1,2,3},{4,5},{6}};

    System.out.println(arr);
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);

    System.out.println(arr[0][0]); //1
    System.out.println(arr[1][0]); //4
    System.out.println(arr[2][0]); //6

    System.out.println(arr[0][1]); //2
    System.out.println(arr[1][1]); //5
    //越界
    System.out.println(arr[2][1]); //错误
    }

     

     

    2.二维数组的遍历

     

    外循环控制的是二维数组的长度,其实就是一维数组的个数。
    内循环控制的是一维数组的长度。
    代码如下

     

    public static void main(String[] args) {
    //定义一个二维数组
    int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};

    //arr[0]就是第一个数组
    //arr[0] = {1,2,3};
    for(int x=0; x<arr[0].length; x++) {
    System.out.println(arr[0][x]);
    }
    System.out.println("--------------");

    for(int x=0; x<arr[1].length; x++) {
    System.out.println(arr[1][x]);
    }
    System.out.println("--------------");

    for(int x=0; x<arr[2].length; x++) {
    System.out.println(arr[2][x]);
    }
    System.out.println("--------------");

    //用循环改进
    for(int x=0; x<3; x++) {
    for(int y=0; y<arr[x].length; y++) {
    System.out.print(arr[x][y]+" ");
    }
    System.out.println();
    }
    System.out.println("--------------");

    //3是我们根据上面的代码得出来的
    //但是,它不能针对任何的数组都可以这样
    //其实外面的这个循环的长度就是二维数组的长度

    for(int x=0; x<arr.length; x++) {
    for(int y=0; y<arr[x].length; y++) {
    System.out.print(arr[x][y]+" ");
    }
    System.out.println();
    }
    System.out.println("--------------");

    //用方法改进
    //调用方法
    printArray2(arr);
    System.out.println("--------------");

    //我们再来一个列数是变化的
    int[][] arr2 = {{1,2,3},{4,5},{6}};
    printArray2(arr2);
    }

    /*
    需求:遍历二维数组
    两个明确:
    返回值类型:void
    参数列表:int[][] arr
    */
    public static void printArray2(int[][] arr) {
    for(int x=0; x<arr.length; x++) {
    for(int y=0; y<arr[x].length; y++) {
    System.out.print(arr[x][y]+" ");
    }
    System.out.println();
    }
    }
    3.二维数组累加求和
    核心代码
    //通过遍历就可以得到每一个二维数组的元素。
    for(int x=0; x<arr.length; x++)
    {
    for(int y=0; y<arr[x].length; y++)
    {
    //把元素累加即可。
    sum += arr[x][y];
    }
    }

     

    4.Java参数传递问题
    Java中的参数传递问题:
    基本类型:形式参数的改变对实际参数没有影响。
    引用类型:形式参数的改变直接影响实际参数。

     

    例子
    public static void main(String[] args) {
    int a = 10;
    int b = 20;
    System.out.println("a:"+a+",b:"+b); //a:10,b:20
    change(a,b);
    System.out.println("a:"+a+",b:"+b); //??? a:10,b:20

     

    int[] arr = {1,2,3,4,5};
    change(arr);
    System.out.println(arr[1]); //??? 4
    }

     

    public static void change(int a,int b) { //a=10,b=20
    System.out.println("a:"+a+",b:"+b); //a:10,b:20
    a = b; //a=20
    b = a + b; //b=40
    System.out.println("a:"+a+",b:"+b); //a:20,b:40
    }

     

    public static void change(int[] arr) { //arr={1,2,3,4,5};
    for(int x=0; x<arr.length; x++) {
    if(arr[x]%2==0) {
    arr[x]*=2;
    }
    }
    //arr={1,4,3,8,5};
    }

     

    一句话:在Java中,只有值传递,只不过基本类型传递的是基本类型的数据值,而引用类型传递的是地址值

     

    6.面向对象思想
    面向对象是基于面向过程的编程思想。

    面向过程:强调的是每一个功能的步骤
    面向对象:强调的是对象,然后由对象去调用功能

    2:面向对象的思想特点
    A:是一种更符合我们思想习惯的思想
    B:可以将复杂的事情简单化
    C:将我们从执行者变成了指挥者

    举例:
    买电脑:
    面向过程:我的了解电脑--了解我自己的需求--找对应的参数信息--去中关村买电脑--讨价还价--买回电脑
    面向对象:我知道我要买电脑 -- 班长去给我买 -- 班长就买回来了
    洗衣服:
    面向过程:把衣服脱下--找一个盆--放点洗衣粉--加点水--把衣服扔进去--搓一搓--清洗衣服--拧干--晾起来
    面向对象:把衣服脱下--打开全自动洗衣机--扔进去--一键即可--晾起来
    吃饭:
    面向过程:去超市买菜--摘菜--洗菜--切菜--炒菜--盛起来--吃
    面向对象:上饭店吃饭,你--服务员(点菜)--厨师(做菜)--服务员(端菜)--吃

     

    3.开发,设计,特征
    面向对象开发
    就是不断的创建对象,使用对象,指挥对象做事情。

    面向对象设计
    其实就是在管理和维护对象之间的关系。

     

    面向对象特征
    封装(encapsulation)
    继承(inheritance)
    多态(polymorphism)
    4.面向过程与面向对象
    举例:把大象装进冰箱

     

    面向过程:
    动作有哪些呢?
    A:打开冰箱门
    B:装进大象
    C:关闭冰箱门

     

    面向对象:
    我们怎么才能更符合面向对象思想呢?
    A:有哪些类呢?
    B:每个类有哪些东西呢?
    C:类与类直接的关系是什么呢?

    把大象装进冰箱的分析? (如何分析有哪些类呢?UML。名词提取法。)
    A:有哪些类呢?
    大象
    冰箱
    Demo
    B:每个类有哪些东西呢?
    大象:
    进去
    冰箱:
    开门
    关门
    Demo:
    main方法
    C:类与类直接的关系是什么呢?
    Demo中使用大象和冰箱类的功能。
    5.现实世界中是如何描述一个事物的呢?
    举例:学生
    姓名,年龄,性别...
    学习,吃饭,睡觉

    属性:该事物的描述信息
    行为:该事物能够做什么

    我们学习编程语言,是为了模拟现实世界的事物的。
    而我们学习的编程语言Java中最基本的单位是:类。
    所以,我们就应该把事物通过类来体现出来:
    由此,我们就得到了现实世界事物和类的对应关系:

     

    事物: 类:
    属性 成员变量
    行为 成员方法


    类:是一组相关的属性和行为的集合。是一个抽象的概念。
    对象:是该类事物的具体表现形式。具体存在的个体。

     

    举例:
    学生:类
    班长:对象
    =================================
    现实世界的事物
    事物:
    属性 人的身高,体重等
    行为 人可以学习,吃饭等

     

    Java中用class描述事物也是如此
    类:
    成员变量 就是事物的属性
    成员方法 就是事物的行为
    定义类其实就是定义类的成员(成员变量和成员方法)

     

    ===========================================================
    6.
    在一个java文件中写两个类:一个基本的类,一个测试类。
    注意:文件名称和测试类名称一致。

    如何使用呢?
    创建对象使用。

    如何创建对象呢?
    格式:类名 对象名 = new 类名();

    如何使用成员变量呢?
    对象名.变量名
    如何使用成员方法呢?
    对象名.方法名(...)
    7……

     

     一个对象的内存图

    二个对象的内存图

     

     

    三个对象的内存图

     

     

     

    使用类的内容
    a:创建对象? 格式
    类名 对象名 = new 类名();
    b:如何使用成员变量和成员方法呢
    对象名.成员变量
    对象名.成员方法()

     

    day07
    1.成员变量和局部变量
    一个实例
    class Varialbe {
    //成员变量
    //int num = 10;
    int num; //0

    public void show() {
    //int num2 = 20; //局部变量
    //可能尚未初始化变量num2
    //int num2; //没有默认值
    int num2 = 20;
    System.out.println(num2);

    //int num = 100;
    System.out.println(num);
    }
    }

     


    class VariableDemo {
    public static void main(String[] args) {
    Varialbe v = new Varialbe();

    System.out.println(v.num); //访问成员变量

    v.show();

    }
    }

     

     

     

    成员变量和局部变量的区别?
    A:在类中的位置不同
    成员变量:在类中方法外
    局部变量:在方法定义中或者方法声明上
    B:在内存中的位置不同
    成员变量:在堆内存
    局部变量:在栈内存
    C:生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    D:初始化值不同
    成员变量:有默认初始化值
    局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

    注意事项:
    局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则
    例如,上面关于num的输出问题

     

    2.
    形式参数的问题:
    基本类型:形式参数的改变不影响实际参数(值传递)
    引用类型:形式参数的改变直接影响实际参数(引用传递)
    ===============================================================================
    //形式参数是引用类型
    class Student {
    public void show() {
    System.out.println("我爱学习");
    }
    }

     

    class StudentDemo {
    //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
    public void method(Student s) {
    //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
    s.show();
    }
    }

     

    class ArgsTest {
    public static void main(String[] args) {
    //形式参数是引用类型的调用
    //需求:我要调用StudentDemo类中的method()方法
    StudentDemo sd = new StudentDemo();
    //创建学生对象
    Student s = new Student();
    sd.method(s); //把s的地址给到了这里
    }
    }
    ===============================================================================
    3.匿名对象
    匿名对象:就是没有名字的对象。

    匿名对象的应用场景:
    A:调用方法,仅仅只调用一次的时候。
    注意:调用多次的时候,不适合。
    那么,这种匿名调用有什么好处吗?
    有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
    B:匿名对象可以作为实际参数传递

     

    class Student {
    public void show() {
    System.out.println("我爱学习");
    }
    }

     

    class StudentDemo {
    public void method(Student s) {
    s.show();
    }
    }

     

    class NoNameDemo {
    public static void main(String[] args) {
    //带名字的调用
    Student s = new Student();//虽然也在堆内存里,但是有s地址连接着new Student(),new Student()不会这么快消失(只要s还存在)
    s.show();
    s.show();//同一个对象被调用两次
    System.out.println("--------------");

    //匿名对象
    //new Student();
    //匿名对象调用方法
    new Student().show();
    new Student().show(); //这里其实是重新创建了一个新的对象。因为这是在堆内存的,调用完就消失了
    System.out.println("--------------");

     

    匿名对象可以作为实际参数传递
    //匿名对象作为实际参数传递
    StudentDemo sd = new StudentDemo();
    //Student ss = new Student();
    //sd.method(ss); //这里的s是一个实际参数
    //匿名对象
    sd.method(new Student());

    //在来一个
    new StudentDemo().method(new Student());

     

    4.
    private:私有的。可以修饰成员变量和成员方法。
    注意:被private修饰的成员只能在本类中访问。
    封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
    例子
    class Student {
    String name;
    private int age;

    //写一个方法对数据进行校验

     

    public void setAge(int a) {
    if(a < 0 || age > 120) {
    System.out.println("你给的年龄有问题");
    }else {
    age = a;
    }
    }


    //show()方法,显示所有成员变量值
    public void show() {
    System.out.println("姓名:"+name);
    System.out.println("年龄:"+age);
    }
    }

     

    class StudentDemo {
    public static void main(String[] args) {
    //创建学生对象
    Student s = new Student();
    s.show();
    System.out.println("--------------");

    //给成员变量赋值
    s.name = "林青霞";
    //s.age = 27;
    s.setAge(27);
    s.show();
    System.out.println("--------------");

    //给age赋值
    //s.age = -27; //这个数据是不合理的,加上private后age只能在Student类中使用而不能在StudentDemo中使用
    //通过方法给值
    s.setAge(-27);
    s.show();
    System.out.println("--------------");
    }
    }

     

    5.封装和private的应用:
    A:把成员变量用private修饰
    B:提高对应的getXxx()和setXxx()方法

     

    class Student
    {
    private String name;

     

    private int age;

    public String getName()
    {
    return name;
    }

    public void setName(String n)
    {
    name = n;
    }

    public int getAge()
    {
    return age;
    }

    public void setAge(int a)
    {
    age = a;
    }
    }

     

    //测试类
    class StudentTest {
    public static void main(String[] args)
    {
    //创建学生对象
    Student s = new Student();

    //使用成员变量
    //错误:被私有修饰了,外界不能直接访问了
    //System.out.println(s.name+"---"+s.age);
    System.out.println(s.getName()+"---"+s.getAge());

    //给成员变量赋值
    //s.name = "林青霞";
    //s.age = 27;
    //通过方法给赋值
    s.setName("林青霞");
    s.setAge(27);
    System.out.println(s.getName()+"---"+s.getAge());
    }
    }

     

    6.this关键字
    this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。

    注意:谁调用这个方法,在该方法内部的this就代表谁。

    this的场景:
    解决局部变量隐藏成员变量

     

    例子
    ===================================================================
    class Student {
    private String name;

     

    public String getName() {
    return name;
    /*public void setName(String n)
    {
    name = n;//不用this关键字的以前用法,但是s的名字不够鲜明于是改为name
    }*/
    public void setName(String name) { //name = "林青霞";
    //name = name; //变量的使用规则:就近原则
    //这里是类名,目前还没有说过类似的用法,所以这个是有问题的
    //这里的调用只能通过对象名
    //这个对象如果存在,它应该代表的是Student的一个对象。
    //那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this
    //Student.name = name;
    this.name = name;
    }
    }

     

    class StudentTest {
    public static void main(String[] args) {
    //创建学生对象
    Student s = new Student();

    //给成员变量赋值
    s.setName("林青霞");

    System.out.println(s.getName());
    }
    }
    ==================================================================================
    this:哪个对象调用那个方法,this就代表那个对象
    this关键字的内存图解.bmp

     

     

    7.构造方法

    构造方法:
    给对象的数据进行初始化

     

    格式:
    A:方法名与类名相同
    B:没有返回值类型,连void都没有
    C:没有具体的返回值

     

    例子
    class Student {

    public Student() {
    System.out.println("这是构造方法");
    }
    }

     

    class ConstructDemo {
    public static void main(String[] args) {
    //创建对象
    Student s = new Student();
    System.out.println(s); //Student@e5bbd6
    }
    }

     


    构造方法的注意事项:
    A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
    例子:
    class Student
    {

    }
    class ConstructDemo2
    {
    public static void main(String[] args)
    {
    //创建对象
    Student s = new Student();
    }
    }

    图解反编译前

     

     

    反编译后

    通过反编译可知


    主要是new Student()引发的构造方法Student(反编译中的图解)public 为默认所以上图不显示

     

    B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。(构造方法也可以重载,即带不同参数--默认不带参数)
    注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法

     

    8.
    类的组成:成员变量,成员方法
    今天我们又加入了一个新的成员:构造方法。
    以后再提类的组成:
    成员变量
    构造方法
    成员方法

     

    图解

     

    9.注意:
    import必须出现在所有的class前面。
    例如

    1 import java.util.Scanner;
    2 class ……
    3 {
    4 
    5 }
    6 class ……
    7 {
    8 
    9 }

     

    10.static
    static的特点:(它可以修饰成员变量,还可以修饰成员方法)
    A:随着类的加载而加载
    回想main方法。
    B:优先于对象存在
    C:被类的所有对象共享
    举例:咱们班级的学生应该共用同一个班级编号。
    其实这个特点也是在告诉我们什么时候使用静态?
    如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
    举例:
    饮水机(用静态修饰)(饮水机可以多人共享使用)
    水杯(不能用静态修饰)(水杯只能自己一个人用,原则上不可以共享,每个人都有一个)
    D:可以通过类名调用
    其实它本身也可以通过对象名调用。
    推荐使用类名调用。

    静态修饰的内容一般我们称其为:与类相关的,类成员
    静态变量也可以通过类名调用.png

     
    class Student {
     //非静态变量
     int num = 10;
     
     //静态变量
     static int num2 = 20;
    }
     
    class StudentDemo {
     public static void main(String[] args) {
      Student s = new Student();
      System.out.println(s.num);
     
      System.out.println(Student.num2);
      System.out.println(s.num2);
     }
    }
     
    static的内存图解

     


    11.static关键字注意事项
    A:在静态方法中是没有this关键字的
    如何理解呢?
    静态是随着类的加载而加载,this是随着对象的创建而存在。
    静态比对象先存在。
    B:静态方法只能访问静态的成员变量和静态的成员方法
    静态方法:
    成员变量:只能访问静态变量
    成员方法:只能访问静态成员方法
    非静态方法:
    成员变量:可以是静态的,也可以是非静态的
    成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
    简单记:
    静态只能访问静态。(非静态可以访问一切)
    例子

     1 class Teacher {
     2 public int num = 10;
     3 public static int num2 = 20;
     4 
     5 public void show() {
     6 System.out.println(num); //语句1,隐含的告诉你访问的是成员变量
     7 System.out.println(this.num); //语句2,明确的告诉你访问的是成员变量,与语句1相同效果
     8 System.out.println(num2);
     9 
    10 //function();
    11 //function2();
    12 }
    13 
    14 public static void method() {
    15 //无法从静态上下文中引用非静态 变量 num
    16 //System.out.println(num);
    17 System.out.println(num2);
    18 
    19 //无法从静态上下文中引用非静态 方法 function()
    20 //function();
    21 function2();
    22 }
    23 
    24 public void function() {
    25 
    26 }
    27 
    28 public static void function2() {
    29 
    30 }
    31 }
    32 
    33 class TeacherDemo {
    34 public static void main(String[] args) {
    35 //创建对象
    36 Teacher t = new Teacher();
    37 t.show();
    38 System.out.println("------------");
    39 t.method();
    40 }
    41 }

     

     

    12.静态变量和成员变量的区别
    所属不同
    静态变量属于类,所以也称为为类变量
    成员变量属于对象,所以也称为实例变量(对象变量)
    内存中位置不同
    静态变量存储于方法区的静态区
    成员变量存储于堆内存
    内存出现时间不同
    静态变量随着类的加载而加载,随着类的消失而消失
    成员变量随着对象的创建而存在,随着对象的消失而消失
    调用不同
    静态变量可以通过类名调用,也可以通过对象调用
    成员变量只能通过对象名调用
    13.
    main方法的格式讲解:
    public static void main(String[] args) {...}

    public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
    static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
    void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
    main:是一个常见的方法入口。我见过的语言都是以main作为入口。
    String[] args:这是一个字符串数组。值去哪里了?
    这个东西到底有什么用啊?怎么给值啊?
    这个东西早期是为了接收键盘录入的数据的。
    格式是:
    java MainDemo hello world java

    例子

     1 class MainDemo {
     2   public static void main(String[] args) {
     3   //System.out.println(args); //[Ljava.lang.String;@175078b
     4   //System.out.println(args.length); //0
     5   //System.out.println(args[0]); //ArrayIndexOutOfBoundsException
     6 
     7   //接收数据后
     8   System.out.println(args); 
     9   System.out.println(args.length); 
    10   //System.out.println(args[0]); 
    11     for(int x=0; x<args.length; x++) {
    12       System.out.println(args[x]);
    13     }
    14   }
    15 }


    补充:
    private是封装的一种表现。
    思考题:构造方法中可不可以有return语句呢?
    可以。而是写成这个样子:return;


    day08
    1.首先要注意,在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。

    2.例子
    ===========================================================================
    class ArrayTool {

    //把构造方法私有,外界就不能在创建对象了
    private ArrayTool(){}

      public static void printArray(int[] arr) {
        for(int x=0; x<arr.length; x++) {
          if(x == arr.length-1) {
          System.out.println(arr[x]);
          }else {
            System.out.print(arr[x]+", ");
            }
        }
      }
    }
    =====================================================
    class ArrayDemo {
      public static void main(String[] args) {
       //定义数组
       int[] arr = {28,55,37,46,19};

      //需求:遍历数组
      /*
      for(int x=0; x<arr.length; x++) {
        if(x == arr.length-1) {
        System.out.println(arr[x]);
        }else {
          System.out.print(arr[x]+", ");
            }
        }
      */

      //如果我有多个数组都要进行遍历,那么,代码的重复度就很高
      //如何改进呢?用方法改进
      //调用
      //静态方法
      //printArray(arr);

      //非静态方法
      //ArrayDemo ad = new ArrayDemo();
      //ad.printArray(arr);

      //测试类的作用:创建其他类的对象,调用其他类的功能。
      //而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
      //定义一个数组的操作类
      //有了数组操作类之后的调用
      //ArrayTool at = new ArrayTool();
      //at.printArray(arr);

      //方法改进为静态后,就可以直接通过类名调用
      ArrayTool.printArray(arr);
      }

      /*
      public static void printArray(int[] arr) {
        for(int x=0; x<arr.length; x++) {
          if(x == arr.length-1) {
          System.out.println(arr[x]);
          }else {
            System.out.print(arr[x]+", ");
             }
          }
      }
      */

      //假设该方法不是静态的
      /*
      public void printArray(int[] arr) {
        for(int x=0; x<arr.length; x++) {
        if(x == arr.length-1) {
          System.out.println(arr[x]);
          }else {
            System.out.print(arr[x]+", ");
          }
        }
      }
      */
      }
    =======================================================================
    3.制作文档注释,文档说明书
    注意:如何制作一个说明书呢?
    A:写一个工具类
    B:对这个类加入文档注释
    怎么加呢?
    加些什么东西呢?
    C:用工具解析文档注释
    javadoc工具
    D:格式
    javadoc -d 目录 -author -version ArrayTool.java

    目录:就可以写一个文件夹的路径

    制作帮助文档出错:
    找不到可以文档化的公共或受保护的类:告诉我们类的权限不够(解决办法:在class前面加public)
    实例
    =================================================================================
    /**
    * 这是针对数组进行操作的工具类
    * @author 刘意
    * @version V.10
    */
    public class ArrayTool {

    //把构造方法私有,外界就不能在创建对象了
    /**
    * 这是私有构造
    */
      private ArrayTool(){}

    /**
    * 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...]
    * @param arr 这是要被遍历的数组
    */
    public static void printArray(int[] arr) {
      System.out.print("[");
      for(int x=0; x<arr.length; x++) {
        if(x == arr.length-1) {
        System.out.println(arr[x]+"]");
        }else {
          System.out.print(arr[x]+", ");
           }
       }
    }

    /**
    * 这是获取数组中最大值的方法
    * @param arr 这是要获取最大值的数组
    * @return 返回数组中的最大值
    */
    public static int getMax(int[] arr) {
      int max = arr[0];

      for(int x=1; x<arr.length; x++) {
        if(arr[x] > max) {
          max = arr[x];
          }
      }

      return max;
    }

    /**
    * 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
    * @param arr 被查找的数组
    * @param value 要查找的元素
    * @return 返回元素在数组中的索引,如果不存在,返回-1
    */
    public static int getIndex(int[] arr,int value) {
      int index = -1;

      for(int x=0; x<arr.length; x++) {
        if(arr[x] == value) {
          index = x;
          break;
        }
      }

      return index;
     }
    }
    ==========================================================================================
    4.如何查看API帮助文档
    1:打开帮助文档
    2:点击显示,找到索引,看到输入框
    3:知道你要找谁?以Scanner举例
    4:在输入框里面输入Scanner,然后回车
    5:看包
    java.lang包下的类不需要导入,其他的全部需要导入。

    要导入:
    java.util.Scanner
    6:再简单的看看类的解释和说明,别忘了看看该类的版本
    7:看类的结构
    成员变量 字段摘要
    构造方法 构造方法摘要
    成员方法 方法摘要
    8:学习构造方法
    A:有构造方法 就创建对象
    B:没有构造方法 成员可能都是静态的
    9:看成员方法
    A:左边
    是否静态:如果静态,可以通过类名调用
    返回值类型:人家返回什么,你就用什么接收。
    B:右边
    看方法名:方法名称不要写错
    参数列表:人家要什么,你就给什么;人家要几个,你就给几个


    实例
    Math
    Math:类包含用于执行基本数学运算的方法

    由于Math类在java.lang包下,所以不需要导包。
    特点:
    没有构造方法,因为它的成员全部是静态的。

    掌握一个方法:
    获取随机数
    public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
    ===========================================
    class MathDemo {
      public static void main(String[] args) {
      //获取一个随机数
      //double d = Math.random();
      //System.out.println(d);

      //需求:我要获取一个1-100之间的随机数,肿么办?
        for(int x=0; x<100; x++) {
          int number = (int)(Math.random()*100)+1;
          System.out.println(number);
        }
      }
    }
    ========================

    实例2
    /*
    猜数字小游戏(1-100)
    */
    import java.util.Scanner;
    class GuessNumber
    {
      public static void main(String[] args)
    {
    //程序产生一个随机数
    int number = (int)(Math.random()*100)+1;
    
    
    //给出多次猜的机会,猜中就结束
    while(true)
    {
        //键盘录入数据
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你要猜的数据(1-100):");
        int guessNumber = sc.nextInt();
    
        if(guessNumber>number)
        {
          System.out.println("你要猜的数据"+guessNumber+"大了");
        }
        else if(guessNumber<number)
        {
          System.out.println("你要猜的数据"+guessNumber+"小了");
        }
        else
        {
          System.out.println("恭喜你,猜中了");
        }
       }
      }
    }

     

    5.代码块
    局部代码块:局部位置,用于限定变量的生命周期
     实例
     1
     1 /*
     2    代码块
     3  */
     4  class Code
     5  {
     6    
     7  }
     8  class CodeDemo
     9  {
    10      public static void main(String[] args)
    11     {
    12        //局部代码块
    13        {
    14             int x = 10;//只在大括号内使用
    15            System.out.println(x);
    16         }    
    17  
    18       System.out.println(x);//报错,找不到符号
    19      }
    20 }

     

     
    构造代码块:在类中的成员位置,用{}括起来的代码
       特点:每次调用构造方法执行前,都会先执行构造代码块。
       作用:可以把多个构造方法中的共同代码放到一起。
    class Code
    {
       //构造代码块
     {
      //注意这一段外面不加大括号会报错,加大括号后就不报错
      int x = 100;
      System.out.println(x);
     }
     
     public Code()
     {
      System.out.println("code");//这个打印语句在第三个也就是最后一个才输出
     }
     
     {
        int y = 200;
        System.out.println(y);
     }
    }
     
    class CodeDemo
    {
     public static void main(String[] args)
     {
        Code c = new Code();//每一次调用构造方法,都会先执行构造代码块,然后才执行构造方法里面的内容
     }
    }
     
     
     
    静态代码块:在类中的成员位置用{}括起来的代码。只不过它用static修饰了
      作用:一般是对类进行初始化(随着类的加载而加载)
    class Code
    {
     //静态代码块
     static
     {
        int a = 1000;
        System.out.println(a);
     }
     
     //构造代码块
     {
      int x = 10;
      System.out.println(x);
     }
     
     //静态代码块
     static
     {
      int b = 2000;
      System.out.println(b);//执行顺序是:先打印a(1000),再打印b(2000),最后才打印x(10)
     }
    }
     
     
    由上图可以知道,1000只打印了一次,说明静态代码块只执行一次。
     
    面试题:
     静态代码块,构造代码块,构造方法的执行顺序?
     静态代码块 --- 构造代码块 --- 构造方法
     而且:静态代码块:只执行一次
        构造代码块:每次调用构造方法都执行
     
     
     
     
     
    由上图可知静态代码块只执行一次,第二次new Student()的时候不打印静态代码块
     
    6.继承 extend
     好处:
      A:提高了代码的复用性
      B:提高了代码的维护性
      C:让类与类之间产生了关系,是多态的前提
     
     类与类产生了关系,其实也是继承的一个弊端:
     类的耦合性增强了。
     
      开发的原则:低耦合,高内聚。
      耦合:类与类的关系
      内聚:就是自己完成某件事情的能力
     
    注意:Java不支持多继承,但支持多层继承
     
    Java中继承的特点:
      A:Java只支持单继承,不支持多继承。
       有些语言是支持多继承,格式:extends 类1,类2,...
      B:Java支持多层继承(继承体系)
     
     class Father {}
     class Mother {}
     class Son exnteds Father {} //正确的
     class Son extends Father,Mother {} // 错误的
     
     Java支持多层继承(继承体系)
     class A{}
     class B extends A{}
     class C extends B{}
     并且子类可以直接使用父类的父类的方法
     
     例子
     class GrandFather {
     public void show() {
      System.out.println("我是爷爷");
     }
    }
     
    class Father extends GrandFather {
       public void method(){
        System.out.println("我是老子");
       }
    }
     
    class Son extends Father {}
     
    class ExtendsDemo2 {
       public static void main(String[] args) {
        Son s = new Son();
        s.method(); //使用父亲的
        s.show(); //使用爷爷的
       }
    }
     
    7.继承的注意事项:
     A:子类只能继承父类所有非私有的成员(成员方法和成员变量)(也就是说,父类带private的方法,变量都不可以访问)
     B:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
     C:不要为了部分功能而去继承
     
    什么时候考虑使用继承呢?
      继承其实体现的是一种关系:"is a"。
       Person
        Student
        Teacher
       水果
        苹果
        香蕉
        橘子
       
      采用假设法。
       如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
     
    8.类的组成:
      成员变量:
      构造方法:
      成员方法:
     类的组成部分的各自关系。
     
     继承中成员变量的关系:
      A:子类中的成员变量和父类中的成员变量名称不一样
     
      B:子类中的成员变量和父类中的成员变量名称一样
       在子类方法中访问一个变量的查找顺序:
        a:在子类方法的局部范围找,有就使用
        b:在子类的成员范围找,有就使用
        c:在父类的成员范围找,有就使用
        d:如果还找不到,就报错。
    示例程序
     1 class Father
     2 {
     3    public int num = 10;
     4 }
     5 class Son extends Father
     6 {
     7    public int num = 20;
     8  
     9    public void show()
    10    {
    11       int num = 30;//就近原则
    12       System.out.println(num);
    13    }
    14 }
    15  
    16 class ExtendsDemo5
    17 {
    18    public static void main(String[] args)
    19    {
    20       Son s = new Son();
    21       s.show();
    22    }
    23 }

     

     
    好了,问题来了,我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?(用this)
    办法(修改于上一个程序)
    public void show() {
      int num = 30;
      System.out.println(num);//就近原则num=30
      System.out.println(this.num);//本类中的num=20
     }
    如果还想要输出父类成员范围的num。怎么办呢
    super关键字
     
    public void show() {
      int num = 30;
      System.out.println(num);//30
      System.out.println(super.num);//父类num=10
     }
     
    总结
    public void show() {
      int num = 30;
      System.out.println(num);//局部num
      System.out.println(this.num);//本类num
      System.out.println(super.num);//父类num
     }
     
    9.this和super的区别
    this代表本类对应的引用。
    super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
     
    怎么用呢?
     A:调用成员变量
      this.成员变量 调用本类的成员变量
      super.成员变量 调用父类的成员变量
     B:调用构造方法
      this(...) 调用本类的构造方法
      super(...) 调用父类的构造方法
     C:调用成员方法
      this.成员方法 调用本类的成员方法
      super.成员方法 调用父类的成员方法
     
    10.继承中构造方法的关系
     A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
     
     B:为什么呢?
      因为子类会继承父类中的数据,可能还会使用父类的数据。
      所以,子类初始化之前,一定要先完成父类数据的初始化。
     
      注意:子类每一个构造方法的第一条语句默认都是:super();
     

    如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
    报错。
    如何解决呢?
    A:在父类中加一个无参构造方法
    B:通过使用super关键字去显示的调用父类的带参构造方法

    C:子类通过this去调用本类的其他构造方法
    子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。

    注意事项:
    this(...)或者super(...)必须出现在第一条语句上。
    如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
    (第一条语句给不给它都默认有一个空的super语句,最好手动说明以免引起冲突)

    11.一个类的初始化过程
    成员变量进行初始化
    默认初始化
    显示初始化
    构造方法初始化

    看程序写结果
    A:一个类的静态代码块,构造代码块,构造方法的执行流程
    静态代码块 > 构造代码块 > 构造方法
    B:静态的内容是随着类的加载而加载
    静态代码块的内容会优先执行
    C:子类初始化之前先会进行父类的初始化

    运行结果是:
    静态代码块Fu
    静态代码块Zi
    构造代码块Fu
    构造方法Fu
    构造代码块Zi
    构造方法Zi
    */

     1 class Fu {
     2     static {
     3             System.out.println("静态代码块Fu");
     4     }
     5 
     6     {
     7         System.out.println("构造代码块Fu");
     8     }
     9 
    10     public Fu() {
    11     System.out.println("构造方法Fu");
    12     }
    13 }
    14 
    15 class Zi extends Fu {
    16     static {
    17         System.out.println("静态代码块Zi");
    18      }
    19 
    20     {
    21         System.out.println("构造代码块Zi");
    22     }
    23 
    24     public Zi() {
    25         System.out.println("构造方法Zi");
    26     }
    27 }
    28 
    29 class ExtendsTest2 {
    30     public static void main(String[] args) {
    31         Zi z = new Zi();
    32     }
    33 }                                            

     

    12. A:成员变量的问题
    int x = 10; //成员变量是基本类型
    Student s = new Student(); //成员变量是引用类型
    B:一个类的初始化过程
    成员变量的初始化
    默认初始化
    显示初始化
    构造方法初始化
    C:子父类的初始化(分层初始化)
    先进行父类初始化,然后进行子类初始化。

    结果:
    YXYZ

    问题:
    虽然子类中构造方法默认有一个super()
    初始化的时候,不是按照那个顺序进行的。
    而是按照分层初始化进行的。
    它仅仅表示要先初始化父类数据,再初始化子类数据。

    例子

     1 class X {
     2     Y b = new Y();
     3      X() {
     4         System.out.print("X");
     5     }
     6 }
     7 
     8 class Y {
     9     Y() {
    10     System.out.print("Y");
    11     }
    12 }
    13 
    14 public class Z extends X {
    15     Y y = new Y();
    16     Z() {
    17         //super (注意这里不要加super())
    18     System.out.print("Z");
    19     }
    20     public static void main(String[] args) {
    21         new Z(); 
    22     }
    23 }
    24 
    25 13.子类方法覆盖父类方法
    26 class Father
    27 {
    28      public void show()
    29     {
    30         System.out.println("show Father");
    31     }
    32 }
    33 
    34 class Son extends Father
    35 {
    36     public void method()
    37     {
    38         System.out.println("method Son");
    39     }
    40 
    41 public void show()
    42 {
    43     System.out.println("show Son");
    44 }
    45 }
    46 class ExtendsDemo8
    47 {
    48     public static void main(String[] args)
    49     {
    50         //创建对象
    51         Son s = new Son();
    52         s.method();
    53         s.show();
    54     }
    55 }                                    

     

    13.方法重写子类中出现了和父类中方法声明一模一样的方法。

    方法重载:
    本类中出现的方法名一样,参数列表不同的方法。与返回值无

    子类对象调用方法的时候:
    先找子类本身,再找父类。

    方法重写的应用:
    当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
    这样,即沿袭了父类的功能,又定义了子类特有的内容。

    例子
    A:定义一个手机类。
    B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
    class Phone {
    public void call(String name) {
    System.out.println("给"+name+"打电话");
    }
    }

    class NewPhone extends Phone {
    public void call(String name) {
    //System.out.println("给"+name+"打电话");
    super.call(name); //避免重复代码
    System.out.println("可以听天气预报了");
    }
    }

    class ExtendsDemo9 {
    public static void main(String[] args) {
    NewPhone np = new NewPhone();
    np.call("林青霞");
    }
    }
    14.方法重写的注意事项
    A:父类中私有方法不能被重写
    因为父类私有方法子类根本就无法继承
    B:子类重写父类方法时,访问权限不能更低(public 高)
    最好就一致
    C:父类静态方法,子类也必须通过静态方法进行重写
    其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中讲解

    子类重写父类方法的时候,最好声明一模一样。

    15.两个面试题

    1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?

    方法重写:
    在子类中,出现和父类中一模一样的方法声明的现象。

    方法重载:
    同一个类中,出现的方法名相同,参数列表不同的现象。


    方法重载能改变返回值类型,因为它和返回值类型无关。


    Override:方法重写
    Overload:方法重载

    2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

    this:代表当前类的对象引用
    super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)

    场景:
    成员变量:
    this.成员变量
    super.成员变量
    构造方法:
    this(...)
    super(...)
    成员方法:
    this.成员方法
    super.成员方法

    16.super
    实例
    //定义人类
    class Person {
    //姓名
    private String name;
    //年龄
    private int age;

    public Person() {
    }

    public Person(String name,int age) { //"林青霞",27
    this.name = name;
    this.age = age;
    }

    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;
    }
    }
    //定义学生类
    class Student extends Person {
    public Student() {}

    public Student(String name,int age) { //"林青霞",27
    //this.name = name;
    //this.age = age;
    super(name,age);
    }
    }
    class ExtendsTest4 {
    public static void main(String[] args) {
    //创建学生对象并测试
    //方式1
    Student s1 = new Student();
    s1.setName("林青霞");
    s1.setAge(27);
    System.out.println(s1.getName()+"---"+s1.getAge());

    //方式2
    Student s2 = new Student("林青霞",27);
    System.out.println(s2.getName()+"---"+s2.getAge());

    }

    补充笔记
    API(Application Programming Interface)
    应用程序编程接口(帮助文档)

    day09
    1.final引入
    继承的代码体现

    由于继承中方法有一个现象:方法重写。
    所以,父类的功能,就会被子类给覆盖调。
    有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
    这个时候,针对这种情况,Java就提供了一个关键字:final

    final:最终的意思。常见的是它可以修饰类,方法,变量。
    2.final
    final可以修饰类,方法,变量

    特点:
    final可以修饰类,该类不能被继承。
    final可以修饰方法,该方法不能被重写。(覆盖,复写)
    final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。

    常量:
    A:字面值常量
    "hello",10,true
    B:自定义常量
    final int x = 10;

    3.final面试题

    4.final修饰变量的初始化时机
    A:被final修饰的变量只能赋值一次。
    B:在构造方法完毕前。(非静态的常量)


    5.多态
    多态概述
    某一个事物,在不同时刻表现出来的不同状态。
    通过猫这个小动物,说猫可以被称为猫,也可以被称为动物。在不同时刻,猫表现出的不同状态,来说明多态.
    举例:
    猫可以是猫的类型。猫 m = new 猫();
    同时猫也是动物的一种,也可以把猫称为动物。
    动物 d = new 猫();

    多态:同一个对象(事物),在不同时刻体现出来的不同状态。
    举例:
    猫是猫,猫是动物。
    水(液体,固体,气态)。

    多态的前提:
    A:要有继承关系。
    B:要有方法重写。
    有父类引用指向子类对象


    5. 多态中的成员访问特点:
    A:成员变量
    编译看左边,运行看左边。(意思是编译和运行都是看父类的,都是访问父类的成员,而变量不存在重写,父类的变量不会被子类覆盖)
    B:构造方法
    创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
    C:成员方法
    编译看左边,运行看右边。(方法存在覆盖,存在方法重写,父类的方法被子类覆盖)
    D:静态方法
    编译看左边,运行看左边。(父类的静态方法不会被子类的静态方法所覆盖)
    (静态和类相关,算不上重写,所以,访问还是左边的)
    由于成员方法存在方法重写,所以它运行看右边。

    完整代码
    class Fu {
    public int num = 100;

    public void show() {
    System.out.println("show Fu");
    }

    public static void function() {
    System.out.println("function Fu");
    }
    }

    class Zi extends Fu {
    public int num = 1000;
    public int num2 = 200;

    public void show() {
    System.out.println("show Zi");
    }

    public void method() {
    System.out.println("method zi");
    }

    public static void function() {
    System.out.println("function Zi");
    }
    }

    class DuoTaiDemo {
    public static void main(String[] args) {
    //要有父类引用指向子类对象。
    //父 f = new 子();
    Fu f = new Zi();
    System.out.println(f.num);
    //找不到符号
    //System.out.println(f.num2);

    f.show();
    //找不到符号
    //f.method();
    f.function();
    }
    }

    6.
    多态的好处:
    A:提高了代码的维护性(继承保证)
    B:提高了代码的扩展性(由多态保证)

    例子(来源网上)
    比如有一个父类superClass,它有2个子类subClass1,subClass2。superClass有一个方法
    func(),两个子类都重写了这个方法。那么我们可以定义一个superClass的引用obj,让它指向一个子类的对象,比如superClass obj = new subClass1();那么我们调用obj.func()方法时候,会进行动态绑定,也就是obj它的实际类型的func()方法,即subClass1的func()方法。同样你写superClass obj = new subClass2();obj.func()其实调用的是subClass2的func()方法。这种由于子类重写父类方法,然后用父类引用指向子类对象,调用方法时候会进行动态绑定,这就是多态。多态对程序的扩展具有非常大的作用,比如你要再有一个subClass3,你需要改动的东西会少很多,要是使用了配置文件那就可以不动源代码了。


    7.多态的弊端:
    不能使用子类的特有功能。(因为编译左边)
    Fu f = new Zi();//f不能调用Fu中没有而Zi特有的功能
    想使用子类的特有功能?行不行?
    行。

    怎么用呢?
    A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
    B:把父类的引用强制转换为子类的引用。(向下转型)

    对象间的转型问题:
    向上转型:
    Fu f = new Zi();
    向下转型:
    Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
    实例
    class Fu {
    public void show() {
    System.out.println("show fu");
    }
    }

    class Zi extends Fu {
    public void show() {
    System.out.println("show zi");
    }

    public void method() {
    System.out.println("method zi");
    }

    }

    class DuoTaiDemo4 {
    public static void main(String[] args) {
    //测试
    Fu f = new Zi();
    f.show();
    //f.method();

    //创建子类对象,太占内存
    //Zi z = new Zi();
    //z.show();
    //z.method();

    //你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
    //如果可以,但是如下
    Zi z = (Zi)f;//强制类型转换
    z.show();
    z.method();
    }
    }

     多态继承中的内存图解

    多态中的对象变化内存图解

    ClassCastException:类型转换异常
     一般在多态的向下转型中容易出现
     
     
    8.多态案例
     1 /*
     2  不同地方饮食文化不同的案例
     3 */
     4 class Person {
     5  public void eat() {
     6   System.out.println("吃饭");
     7  }
     8 }
     9  
    10 class SouthPerson extends Person {
    11    public void eat() {
    12     System.out.println("炒菜,吃米饭");
    13    }
    14  
    15    public void jingShang() {
    16      System.out.println("经商");
    17    }
    18 }
    19  
    20 class NorthPerson extends Person {
    21    public void eat() {
    22     System.out.println("炖菜,吃馒头");
    23    }
    24  
    25    public void yanJiu() {
    26     System.out.println("研究");
    27    }
    28 }
    29  
    30 class DuoTaiTest2 {
    31    public static void main(String[] args) {
    32     //测试
    33     //南方人
    34     Person p = new SouthPerson();
    35     p.eat();
    36     System.out.println("-------------");
    37     //转换成南方人
    38     SouthPerson sp = (SouthPerson)p;
    39     sp.eat();
    40     sp.jingShang();
    41     System.out.println("-------------");
    42  
    43     //北方人
    44     p = new NorthPerson();
    45     p.eat();
    46     System.out.println("-------------");
    47     //转换成北方人
    48     NorthPerson np = (NorthPerson)p;
    49     np.eat();
    50     np.yanJiu();
    51    }
    52 }
    53  
     
    9.抽象类的概述:
      动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
      我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
     
     抽象类的特点:
      A:抽象类和抽象方法必须用abstract关键字修饰
      B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
      C:抽象类不能实例化
       因为它不是具体的。
       抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
       用于子类访问父类数据的初始化
      D:抽象的子类
       a:如果不想重写抽象方法,该子类是一个抽象类。
       b:重写所有的抽象方法,这个时候子类是一个具体的类。
       
      抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
       Animal a = new Cat();
     
    实例
    //abstract class Animal //抽象类的声明格式
    abstract class Animal {
     //抽象方法
     //public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体
     public abstract void eat();
     
     public Animal(){} //构造器
    }
     
    //子类是抽象类
    abstract class Dog extends Animal {}
     
    //子类是具体类,重写抽象方法
    class Cat extends Animal {
     public void eat() {
      System.out.println("猫吃鱼");
     }
    }
     
    class AbstractDemo {
     public static void main(String[] args) {
      //创建对象
      //Animal是抽象的; 无法实例化
      //Animal a = new Animal();
      //通过多态的方式
      Animal a = new Cat();
      a.eat();
     }
    }
     
     
    10. 抽象类的成员特点:
      成员变量:既可以是变量,也可以是常量。
      构造方法:有。
         用于子类访问父类数据的初始化。
      成员方法:既可以是抽象的,也可以是非抽象的。
     
     抽象类的成员方法特性:
      A:抽象方法 强制要求子类做的事情。
      B:非抽象方法 子类继承的事情,提高代码复用性。
     
    例子
     1 abstract class Animal {
     2    public int num = 10;//变量
     3    public final int num2 = 20;//常量
     4  
     5    public Animal() {}//无参构造方法
     6  
     7    public Animal(String name,int age){}//带参构造方法
     8  
     9    public abstract void show();//抽象方法
    10  
    11    public void method() {//非抽象方法
    12     System.out.println("method");
    13    }
    14 }
    15  
    16 class Dog extends Animal {
    17    public void show() {
    18     System.out.println("show Dog");
    19    }
    20 }
    21  
    22 class AbstractDemo2 {
    23    public static void main(String[] args) {
    24     //创建对象
    25     Animal a = new Dog();
    26     a.num = 100;
    27     System.out.println(a.num);
    28     //a.num2 = 200;
    29     System.out.println(a.num2);
    30     System.out.println("--------------");
    31     a.show();
    32     a.method();
    33    }
    34 }
     
    11.体现多态的例子
    abstract class Teacher {
     //姓名
     private String name;
     //年龄
     private int age;
     
     public Teacher() {}
     
     public Teacher(String name,int age) {
      this.name = name;
      this.age = age;
     }
     
     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 abstract void teach();
    }
     
    //基础班老师类
    class BasicTeacher extends Teacher {
     public BasicTeacher(){}
     
     public BasicTeacher(String name,int age) {
      super(name,age);
     }
     
     public void teach() {
      System.out.println("基础班老师讲解JavaSE");
     }
    }
     
    //就业班老师类
    class WorkTeacher extends Teacher {
     public WorkTeacher(){}
     
     public WorkTeacher(String name,int age) {
      super(name,age);
     }
     
     public void teach() {
      System.out.println("就业班老师讲解JavaEE");
     }
    }
     
    class AbstractTest2 {
     public static void main(String[] args) {
      //具体的类测试,自己玩
     
      //测试(多态)
      //基础班老师
      Teacher t = new BasicTeacher();
      t.setName("刘意");
      t.setAge(30);
      System.out.println(t.getName()+"---"+t.getAge());
      t.teach();
      System.out.println("--------------");
     
      t = new BasicTeacher("刘意",30);
      System.out.println(t.getName()+"---"+t.getAge());
      t.teach();
      System.out.println("--------------");
     
      //就业班老师
      t = new WorkTeacher();
      t.setName("林青霞");
      t.setAge(27);
      System.out.println(t.getName()+"---"+t.getAge());
      t.teach();
      System.out.println("--------------");
     
      t = new WorkTeacher("林青霞",27);
      System.out.println(t.getName()+"---"+t.getAge());
      t.teach();
     }
    }
    上述程序的t被多次使用作很多用途,体现了一个t 的多态
     
    12.多态小问题
    一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
     A:可以。
     B:不让创建对象。
     
    abstract不能和哪些关键字共存?
     private 冲突(private要求不能重写,而abstract要求重写)
     final 冲突
     static 无意义
     
    13.接口
    接口的特点
    接口的特点:
      A:接口用关键字interface表示
       interface 接口名 {}
      B:类实现接口用implements表示
       class 类名 implements 接口名 {}
      C:接口不能实例化
       那么,接口如何实例化呢?
       按照多态的方式来实例化。
      D:接口的子类
       a:可以是抽象类。但是意义不大。
       b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
     
     由此可见:
      A:具体类多态(几乎没有)
      B:抽象类多态(常用)
      C:接口多态(最常用)
    实例
    //定义动物培训接口
    interface AnimalTrain {
     public abstract void jump();
    }
     
    //抽象类实现接口
    abstract class Dog implements AnimalTrain {
    }
     
    //具体类实现接口
    class Cat implements AnimalTrain {
     public void jump() {
      System.out.println("猫可以跳高了");
     }
    }
     
    class InterfaceDemo {
     public static void main(String[] args) {
      //AnimalTrain是抽象的; 无法实例化
      //AnimalTrain at = new AnimalTrain();
      //at.jump();
     
      AnimalTrain at = new Cat();
      at.jump();
     }
    }
    接口的变量默认是常量
     
     
    接口的变量默认是静态的
     
    14.接口成员特点
      成员变量;只能是常量,并且是静态的。
        默认修饰符:public static final
        建议:自己手动给出。
      构造方法:接口没有构造方法。
      成员方法:只能是抽象方法。
        默认修饰符:public abstract
        建议:自己手动给出。
     
     所有的类都默认继承自一个类:Object。
     类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
    实例
    interface Inter {
     public int num = 10;
     public final int num2 = 20;
     public static final int num3 = 30;
     
     //错误: 需要<标识符>
     //public Inter() {}
     
     //接口方法不能带有主体
     //public void show() {}
     
     //abstract void show(); //默认public
     public void show(); //默认abstract
    }
     
    //接口名+Impl这种格式是接口的实现类格式
    /*
    class InterImpl implements Inter {
     public InterImpl() {
      super();
     }
    }
    */
     
    class InterImpl extends Object implements Inter {
     public InterImpl() {
      super();
     }
     
     public void show() {}
    }
     
    //测试类
    class InterfaceDemo2 {
     public static void main(String[] args) {
      //创建对象
      Inter i = new InterImpl();
      System.out.println(i.num);
      System.out.println(i.num2);
      //i.num = 100;
      //i.num2 = 200;
      //System.out.println(i.num); //无法为最终变量num分配值
      //System.out.println(i.num2);//无法为最终变量num2分配值
      System.out.println(Inter.num);
      System.out.println(Inter.num2);
      System.out.println("--------------");
     }
    }
     
     
    15.类与类,类与接口,接口与接口的关系  
    类与类:
      继承关系,只能单继承,可以多层继承。 层与层之间还是单继承。
     类与接口:
      实现关系,可以单实现,也可以多实现。
      并且还可以在继承一个类的同时实现多个接口。
     接口与接口:
      继承关系,可以单继承,也可以多继承。(也就是说,java的类只能单继承,但是java的接口可以多继承)
    例子
    interface Father {
     public abstract void show();
    }
     
    interface Mother {
     public abstract void show2();
    }
     
    interface Sister extends Father,Mother {
     
    }
     
    //class Son implements Father,Mother //多实现
    class Son extends Object implements Father,Mother {
     public void show() {
      System.out.println("show son");
     }
     
     public void show2() {
      System.out.println("show2 son");
     }
    }
     
    class InterfaceDemo3 {
     public static void main(String[] args) {
      //创建对象
      Father f = new Son();
      f.show();
      //f.show2(); //报错
     
      Mother m = new Son();
      //m.show(); //报错
      m.show2();
     }
    }
     
     
     
    16.抽象类和接口的区别:
    A:成员区别
     抽象类:
      成员变量:可以变量,也可以常量
      构造方法:有
      成员方法:可以抽象,也可以非抽象
     接口:
      成员变量:只可以常量
      成员方法:只可以抽象
     
    B:关系区别
     类与类
      继承,单继承
     类与接口
      实现,单实现,多实现
     接口与接口
      继承,单继承,多继承
     
    C:设计理念区别
     抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
     接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。(相当于USB插口,可以插上东西实现扩展功能)
     
    补充笔记
    多态的分类:
     a:具体类多态
      class Fu {}
      class Zi extends Fu {}
     
      Fu f = new Zi();
     b:抽象类多态
      abstract class Fu {}
      class Zi extends Fu {}
     
      Fu f = new Zi();
     c:接口多态
      interface Fu {}
      class Zi implements Fu {}
     
      Fu f = new Zi();
     (2)抽象类的特点
      A:抽象类和抽象方法必须用关键字abstract修饰
      B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
      C:抽象类不能实例化
      D:抽象类的子类
       a:是一个抽象类。
       b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。
    抽象类的几个小问题
      A:抽象类有构造方法,不能实例化,那么构造方法有什么用?
       用于子类访问父类数据的初始化
      B:一个类如果没有抽象方法,却定义为了抽象类,有什么用?
       为了不让创建对象
     
    day10
    1.形式参数
            基本类型(太简单,不是我今天要讲解的)
            引用类型
                类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象
                抽象类:需要的是该抽象的类子类对象
                接口:需要的是该接口的实现类对象
        抽象类形式参数举例
        ===============================
        abstract class Person {
        public abstract void study();
    }
     
    class PersonDemo {
        public void method(Person p) {//p; p = new Student();  Person p = new Student(); //多态
            p.study();
        }
    }
     
    //定义一个具体的学生类
    class Student extends Person {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }
     
    class PersonTest {
        public static void main(String[] args) {
            //目前是没有办法的使用的
            //因为抽象类没有对应的具体类
            //那么,我们就应该先定义一个具体类
            //需求:我要使用PersonDemo类中的method()方法
            PersonDemo pd = new PersonDemo();
            Person p = new Student();
            pd.method(p);
        }
    }
    ===========================================================
     
    接口形式参数举例//在这里跟抽象类有点相似
    ====================================
    //定义一个爱好的接口
    interface Love {
        public abstract void love();
    }
     
    class LoveDemo {
        public void method(Love l) { //l; l = new Teacher();  Love l = new Teacher(); 多态
            l.love();
        }
    }
     
    //定义具体类实现接口
    class Teacher implements Love {
        public void love() {
            System.out.println("老师爱学生,爱Java,爱林青霞");
        }
    }
     
    class TeacherTest {
        public static void main(String[] args) {
            //需求:我要测试LoveDemo类中的love()方法
            LoveDemo ld = new LoveDemo();
            Love l = new Teacher();
            ld.method(l);
        }
    }
     
    2.返回值类型
            基本类型:(基本类型太简单,我不准备讲解)
            引用类型:
                类:返回的是该类的对象
                抽象类:返回的是该抽象类的子类对象
                接口:
        返回类型是类举例
        class Student {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }
     
    class StudentDemo {
        public Student getStudent() {
            //Student s = new Student();
            //Student ss = s;
     
            //Student s = new Student();
            //return s;
            return new Student();
        }
    }
     
    class StudentTest2 {
        public static void main(String[] args) {
            //需求:我要使用Student类中的study()方法
            //但是,这一次我的要求是,不要直接创建Student的对象
            //让你使用StudentDemo帮你创建对象
            StudentDemo sd = new StudentDemo();
            Student s = sd.getStudent(); //new Student(); Student s = new Student();
            s.study();
        }
    }
     
    返回类型是抽象类举例
    abstract class Person {
        public abstract void study();
    }
     
    class PersonDemo {
        public Person getPerson() {
            //Person p = new Student();
            //return p;
     
            return new Student();
        }
    }
     
    class Student extends Person {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }
     
    class PersonTest2 {
        public static void main(String[] args) {
            //需求:我要测试Person类中的study()方法
            PersonDemo pd = new PersonDemo();
            Person p = pd.getPerson(); //new Student();  Person p = new Student(); 多态
            p.study();
        }
    }
     
    接口同理
     
    3.链式编程
    /*
        链式编程。
            每次调用完毕方法后,返回的是一个对象。
    */
    class Student {
        public void study() {
            System.out.println("Good Good Study,Day Day Up");
        }
    }
     
    class StudentDemo {
        public Student getStudent() {
            return new Student();
        }
    }
     
    class StudentTest3 {
        public static void main(String[] args) {
            //如何调用的呢?
            StudentDemo sd = new StudentDemo();
            //Student s = sd.getStudent();
            //s.study();
     
            //链式编程
            sd.getStudent().study();
        }
    }
     
    4.包
        A:其实就是文件夹
        B:作用
            a:把相同的类名放到不同的包中
            b:对类进行分类管理
     
        举例
            学生:增加,删除,修改,查询
            老师:增加,删除,修改,查询
     
        方案1:按照功能分
            cn.itcast.add
                AddStudent
                AddTeacher
            cn.itcast.delete
                DeleteStudent
                DeleteTeacher
            cn.itcast.update
                UpdateStudent
                UpdateTeacher
            cn.itcast.find
                FindStudent
                FindTeacher
     
            方案2:按照模块分
            cn.itcast.teacher
                AddTeacher
                DeleteTeacher
                UpdateTeacher
                FindTeacher
            cn.itcast.student
                AddStudent
                DeleteStudent
                UpdateStudent
                FindStudent
    包的定义
            package 包名;
                多级包用.分开即可
     
     
        注意事项:
            A:package语句必须是程序的第一条可执行的代码
            B:package语句在一个java文件中只能有一个
            C:如果没有package,默认表示无包名
    5.带包的编译和运行:
            A:手动式
                a:编写一个带包的java文件。
                b:通过javac命令编译该java文件。
                c:手动创建包名。
                d:把b步骤的class文件放到c步骤的最底层包
                e:回到和包根目录在同一目录的地方,然后运行
                    带包运行
     
            B:自动式
                a:编写一个带包的java文件。
                b:javac编译的时候带上-d即可
                    javac -d . HelloWorld.java
                (注意不要漏掉点号)
                c:回到和包根目录在同一目录的地方,然后运行
                    带包运行。
     
     
     
     
     
    6.导包:
            格式:import 包名;
                这种方式导入是到类的名称。
            注意:我们用谁就导谁。(尽量少用星号*)
     
        面试题:
            package,import,class有没有顺序关系?
            有。
            package > import > class
     
            Package:只能有一个
            import:可以有多个
            class:可以有多个,以后建议是一个
     
     
     
     
     
    7.权限修饰符:
     

    8.修饰符:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
            抽象修饰符:abstract
     
        类:
            权限修饰符:默认修饰符,public
            状态修饰符:final
            抽象修饰符:abstract
     
            用的最多的就是:public
     
        成员变量:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
     
            用的最多的就是:private
     
        构造方法:
            权限修饰符:private,默认的,protected,public
     
            用的最多的就是:public
     
        成员方法:
            权限修饰符:private,默认的,protected,public
            状态修饰符:static,final
            抽象修饰符:abstract
     
            用的最多的就是:public
     
        除此以外的组合规则:
            成员变量:public static final
            成员方法:public static 
                      public abstract
                      public final
     
    9.内部类
     
     
    内部类概述:
            把类定义在其他类的内部,这个类就被称为内部类
            举例:在类A中定义了一个类B,类B就是内部类。
     
        内部的访问特点:
            A:内部类可以直接访问外部类的成员,包括私有。
            B:外部类要访问内部类的成员,必须创建对象。
    */
    class Outer {
        private int num = 10;
     
        class Inner {
            public void show() {
                System.out.println(num);
            }
        }
     
        public void method() {
            //找不到符号
            //show();
     
            Inner i = new Inner();
            i.show();
        }
     
    }
     
    class InnerClassDemo {
        public static void main(String[] args) {
     
        }
    }
     
     
     
     
    10.
        内部类位置
            成员位置:在成员位置定义的类,被称为成员内部类。    
            局部位置:在局部位置定义的类,被称为局部内部类
     
     
        成员位置:在成员位置定义的类,被称为成员内部类。
    class Outer {
        private int num = 10;
     
        //成员位置
        /*
        class Inner {
     
        }
        */
     
     
        public void method() {
            //局部位置
            class Inner {
     
            }
        }
    }
     
    class InnerClassDemo2 {
        public static void main(String[] args) {
     
        }
    }
     
     
     
     
     
    11.成员内部类:
            如何直接访问内部类的成员。
            外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    例子
    class Outer {
        private int num = 10;
     
        class Inner {
            public void show() {
                System.out.println(num);
            }
        }
    }
     
    class InnerClassDemo3 {
        public static void main(String[] args) {
            //需求:我要访问Inner类的show()方法
            //Inner i = new Inner();
            //i.show();
     
            //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
            Outer.Inner oi = new Outer().new Inner();
            oi.show();
        }
    }
     
    12.成员内部类的修饰符:
            private 为了保证数据的安全性
            static 为了方便访问数据
                注意:静态内部类访问的外部类数据必须用静态修饰。
        案例:我有一个人(人有身体,身体内有心脏。)
     
            class Body {
                private class Heart {
                    public void operator() {
                        System.out.println("心脏搭桥");
                    }
                }
     
                public void method() {
                    if(如果你是外科医生) {
                        Heart h = new Heart();
                        h.operator();
                    }
                }
            }
     
            按照我们刚才的讲解,来使用一下
            Body.Heart bh = new Body().new Heart();
            bh.operator();
            //加了private后,就不能被访问了,那么,怎么玩呢?
            Body b =  new Body();
            b.method();
    例子
    ===============================================
    class Outer {
        private int num = 10;
        private static int num2 = 100;
     
        //内部类用静态修饰是因为内部类可以看出是外部类的成员
        public static class Inner {
            public void show() {
                //System.out.println(num);
                System.out.println(num2);
            }
     
            public static void show2() {
                //System.out.println(num);
                System.out.println(num2);
            }        
        }
    }
     
    class InnerClassDemo4 {
        public static void main(String[] args) {
            //使用内部类
            // 限定的新静态类
            //Outer.Inner oi = new Outer().new Inner();
            //oi.show();
            //oi.show2();
     
            //成员内部类被静态修饰后的访问方式是:
            //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
            Outer.Inner oi = new Outer.Inner();
            oi.show();
            oi.show2();
     
            //show2()的另一种调用方式
            Outer.Inner.show2();
        }
    }
    ===========================================================
     
    13.面试题
     
    注意:
            1:内部类和外部类没有继承关系。
            2:通过外部类名限定this对象
                Outer.this
     
     
    14.局部内部类
    局部内部类
            A:可以直接访问外部类的成员
            B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
     
     
    面试题:
            局部内部类访问局部变量的注意事项?
     
     
            A:局部内部类访问局部变量必须用final修饰
            B:为什么呢?
                局部变量是随着方法的调用而调用,随着调用完毕而消失。(个人理解,也就是说,不会立刻消失的method方法已经无法知道它的内部类的方法中的num2究竟是什么来的,毕竟num2已逝去)
                而堆内存的内容并不会立即消失。所以,我们加final修饰。
                加入final修饰后,这个变量就成了常量。既然是常量。你消失了。
                我在内存中存储的是数据20,所以,我还是有数据在使用
                (这个可以用xjad软件反编译理解)
    例子
    ===============================
     1 class Outer {
     2     private int num  = 10;
     3  
     4     public void method() {
     5         //int num2 = 20;
     6         //final int num2 = 20;
     7         class Inner {
     8             public void show() {
     9                 System.out.println(num);
    10                 //从内部类中访问本地变量num2; 需要被声明为最终类型
    11                 System.out.println(num2);//20
    12             }
    13         }
    14  
    15         //System.out.println(num2);
    16  
    17         Inner i = new Inner();
    18         i.show();
    19     }
    20 }
    21  
    22 class InnerClassDemo5 {
    23     public static void main(String[] args) {
    24         Outer o = new Outer();
    25         o.method();
    26     }
    27 }
    =============================================================
    15.匿名内部类
    匿名内部类
            就是内部类的简化写法。
     
        前提:存在一个类或者接口
            这里的类可以是具体类也可以是抽象类。
     
        格式:
            new 类名或者接口名(){
                重写方法;
            }
     
        本质是什么呢?
            是一个继承了该类或者实现了该接口的子类匿名对象。(再次强调,是子类匿名对象,子类!)
     
     
     
     
    当里面有两个方法时,如何调用?
     
    完整代码
     1 interface Inter {
     2     public abstract void show();
     3     public abstract void show2();
     4 }
     5  
     6 class Outer {
     7     public void method() {
     8         //一个方法的时候
     9         /*
    10         new Inter() {
    11             public void show() {
    12                 System.out.println("show");
    13             }
    14         }.show();
    15         */
    16  
    17         //二个方法的时候
    18         /*注释中是一个一个调用
    19         new Inter() {
    20             public void show() {
    21                 System.out.println("show");
    22             }
    23  
    24             public void show2() {
    25                 System.out.println("show2");
    26             }
    27         }.show();
    28  
    29         new Inter() {
    30             public void show() {
    31                 System.out.println("show");
    32             }
    33  
    34             public void show2() {
    35                 System.out.println("show2");
    36             }
    37         }.show2();
    38         */
    39  
    40         //如果我是很多个方法,就很麻烦了
    41         //那么,我们有没有改进的方案呢?
    42         Inter i = new Inter() { //多态
    43             public void show() {
    44                 System.out.println("show");
    45             }
    46  
    47             public void show2() {
    48                 System.out.println("show2");
    49             }
    50         };
    51  
    52         i.show();
    53         i.show2();
    54     }
    55 }
    56  
    57 class InnerClassDemo6 {
    58     public static void main(String[] args) {
    59         Outer o = new Outer();
    60         o.method();
    61     }
    62 }
    63  
    代码解析
    完整代码对比
    interface Person {
        public abstract void study();
    }
     
    class PersonDemo {
        //接口名作为形式参数
        //其实这里需要的不是接口,而是该接口的实现类的对象
        public void method(Person p) {
            p.study();
        }
    }
     
    //实现类
    class Student implements Person {
        public void study() {
            System.out.println("好好学习,天天向上");
        }
    }
     
    class InnerClassTest2 {
        public static void main(String[] args) {
            //测试
            PersonDemo pd = new PersonDemo();
            Person p = new Student();
            pd.method(p);
            System.out.println("--------------------");
     
            //匿名内部类在开发中的使用
            //匿名内部类的本质是继承类或者实现了接口的子类匿名对象
            pd.method(new Person(){
                public void study() {
                    System.out.println("好好学习,天天向上");
                }
            });
        }
    }
     
    16.匿名内部类面试题:
            按照要求,补齐代码
                interface Inter { void show(); }
                class Outer { //补齐代码 }
                class OuterDemo {
                    public static void main(String[] args) {
                          Outer.method().show();
                      }
                }
                要求在控制台输出”HelloWorld”
    ========================================================
    interface Inter { 
        void show(); 
        //public abstract
    }
     
    class Outer { 
        //补齐代码
        public static Inter method() {
            //子类对象 -- 子类匿名对象
            return new Inter() {
                public void show() {
                    System.out.println("HelloWorld");
                }
            };
        }
    }
     
    class OuterDemo {
        public static void main(String[] args) {
            Outer.method().show();
            /*
                1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
                2:Outer.method().show()可以看出method()方法的返回值是一个对象。
                    又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
            */
        }
    }
     
    day10补充笔记
    链式编程
            对象.方法1().方法2().......方法n();
     
            这种用法:其实在方法1()调用完毕后,应该一个对象;
                      方法2()调用完毕后,应该返回一个对象。
                      方法n()调用完毕后,可能是对象,也可以不是对象。
     
     
  • 相关阅读:
    烟花散尽漫说无(參考资料)
    [Leetcode]-Majority Element
    百度移动搜索測试电面
    可删除超炫&amp;多种特效的Card视图(改造自cardsui-for-android开源项目),提供DEMO下载
    关闭 You need to use a Theme.AppCompat theme (or descendant) with this activity解决方法
    Android Snackbar使用方法及小技巧-design
    Android Intent Action 大全
    android权限大全
    Android 判断SD卡是否存在及容量查询
    Android中蓝牙的基本使用----BluetoothAdapter类简介
  • 原文地址:https://www.cnblogs.com/huangtao1996/p/4770709.html
Copyright © 2020-2023  润新知