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

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案例(掌握)
 class HelloWorld {
  public static void main(String[] args) {
   System.out.println("HelloWorld");
  }
 }
 (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)
 
 第一个程序:HelloWorld案例(掌握)
 class HelloWorld {
  public static void main(String[] args) {
   System.out.println("HelloWorld");
  }
 }
 (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的补码和反码。

符号位 数值位

原码: 10110100

反码: 11001011

补码: 11001100

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

符号位 数值位

补码: 11101110

反码: 11101101

原码: 10010010

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中,
long j =  10000000000;
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类型
举例
=================================================================
byte a = 3;

int b = 4;

byte c = a + b;//有问题

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:已知补码求原码。(注意不要漏掉这一步,因为内存中操作的是补码,而我们看到的是补码,所以还要转换成原码)
符号位 数值位
补码: 10000010

反码: 10000001

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

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

17.字符串参与运算
System.out.println("hello"+'a'+1); //输出helloa1,hello优先与‘a’结合
System.out.println('a'+1+"hello"); //输出98hello,‘a’优先与1结合,形成98再与hello结合

System.out.println("5+5="+5+5); //输出5+5=55,字符串与数字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.++,--运算符的使用
//参与运算使用
   int a = 3;
   int b = 4;
   
   int c = a++;
   int d = b--;
   
   System.out.println("a:"+a); //输出为4
   System.out.println("b:"+b); //输出为3
   System.out.println("c:"+c); //输出为3
   System.out.println("d:"+d); //输出为4
 
5.一个面试题
面试题:
short s=1;s = s+1;

short s=1;s+=1;
上面两个代码有没有问题,如果有,那里有问题。
class OperatorTest {
public static void main(String[] args) {
//short s = 1;
//s = s + 1;
//System.out.println(s);

short s = 1;
s += 1; //好像是 s = s + 1;
System.out.println(s);
}
}

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

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;

//&逻辑与
System.out.println((a > b) & (a > c)); //false & false = false
System.out.println((a > b) & (a < c)); //false & true = false
System.out.println((a < b) & (a > c)); //true & false = false
System.out.println((a < b) & (a < c)); //true & true = true

7.Java中&&与&

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

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

//boolean b1 = ((x++ == 3) & (y++ == 4));
//boolean b1 = ((x++ == 3) && (y++ == 4));
//boolean b1 = ((++x == 3) & (y++ == 4));
boolean b1 = ((++x == 3) && (y++ == 4));
System.out.println("x:"+x);
System.out.println("y:"+y);
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:27:03
   
  12.&&:结果和&是一样的,只不过有短路效果。左边是false,右边不执行。
   ||:结果和|是一样的,只不过有短路效果。左边是true,右边不执行。
update 2015年9月14日23:13:32

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语句
例子:
//跳出单层循环
for(int x=0; x<10; x++) {
if(x == 3) {
break;
}
System.out.println("HelloWorld");
}

//跳出多层循环
wc:for(int x=0; x<3; x++) {
nc:for(int y=0; y<4; y++) {
if(y == 2) {
//break nc;
break wc;
}
System.out.print("*");
}
System.out.println();
}

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.方法重载
实例
<span style="font-size:18px;">/*需求:求两个数的和
*/
class  FunctionDemo4
{public static void main(String[] args){//jvm会根据不同的参数去调用不同的功能System.out.println(sum(10,20));System.out.println(sum(10,20,30));System.out.println(sum(10,20,30,40));System.out.println(sum(10.5f,20));}//需求1:求两个数的和public static int sum(int a, int b){System.out.println("int");return a + b;}//需求2:求三个数的和public static int sum(int a, int b, int c){return a + b + c;}//需求3:求四个数的和public static int sum(int a, int b, int c, int d){return a + b + c + d;}public  static float sum(float a,float b){System.out.println("float");return a + b + c + d;}
}</span>

方法重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
方法重载特点:
与返回值类型无关,只看方法名和参数列表
在调用时,虚拟机通过参数列表的不同来区分同名方法
简言之:在同一个类中,方法名相同,参数列表不同,与返回值类型无关。
 参数列表不同:
 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:

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

方式2:

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

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

public static int getIndex(int[] arr,int value) {for(int x=0; x<arr.length; x++) {if(arr[x] == value) {return x;}}return -1;}

方式2( 特别注意!):

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;}}

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.代码块
局部代码块:局部位置,用于限定变量的生命周期
 实例
/*2    代码块3  */4  class Code5  {6    7  }8  class CodeDemo9  {
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 Father2 {3    public int num = 10;4 }5 class Son extends Father6 {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.多态案例
/*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:非抽象方法 子类继承的事情,提高代码复用性。
例子
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软件反编译理解)
例子
===============================
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 类名或者接口名(){
            重写方法;
        }
 
    本质是什么呢?
        是一个继承了该类或者实现了该接口的子类匿名对象。(再次强调,是子类匿名对象,子类!)
当里面有两个方法时,如何调用?
完整代码
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()调用完毕后,可能是对象,也可以不是对象。
 

传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day01~day10)(2015年11月17日20:51:59)相关推荐

  1. 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(2015年10月25日23:28:50)

    day01 win 7系统打开DOS有趣方法:按住shift+右键,单击"在此处打开命令窗口"(注意:在此处可以是任何的文件夹,不一定是桌面) 用DOS删除的文件不可以在回收站恢复 ...

  2. 传z播客 刘意_2015年Java基础视频笔记(day18~day20(2016年3月20日14:36:05)

    day18 1.Map引入 Map是区分于Collection的另外一个"老大" 作为学生来说,是根据学号来区分不同的学生的,那么假设我现在已经知道了学生的学号,我要根据学号去获取 ...

  3. 传z播客 刘意_2015年Java基础视频笔记(day18~day20)(2016年3月20日14:33:31)

    day18 1.Map引入 Map是区分于Collection的另外一个"老大" 作为学生来说,是根据学号来区分不同的学生的,那么假设我现在已经知道了学生的学号,我要根据学号去获取 ...

  4. 传智 刘意 2015年Java基础视频-深入浅出精华版 笔记 day24~day26(2016年4月26日13:11:30)

    day24 1.多线程(JDK5之后的Lock锁的概述和使用)   Lock:           void lock(): 获取锁.           void unlock():释放锁.     ...

  5. 传智播客-刘意-java深入浅出精华版学习笔记Day08

    工具中使用静态: 在同一个类中,main方法只能访问静态方法. [错误:无法从静态上下文中引用非静态,这样的错误一定是因为在main方法中调用了非静态方法.] 对非静态方法来说,只能通过对象(也就是其 ...

  6. 传智播客-刘意-java深入浅出精华版学习笔记Day05

    [视频的前半段讲的是方法.因为方法和函数几乎是一样的,所以直接跳过去了,从数组开始看,唯一有一点需要注意的,就是现在我们暂时都把方法定义为public static型的] 定义格式: 数组的初始化: ...

  7. 《传智播客.Net培训.net视频教程》(.net视频asp.net培训传智播客asp.net视频教程开放课程c#视频移动开发winform SQL ADO.Net HTML JavaScript

    本资源重要通知 2011年4月传智播客.Net培训-免费公开课现场视频 [重磅内容]微软移动开发介绍1-早起的鸟儿有食吃.rar 详情 53.2MB [重磅内容]微软移动开发介绍2-windows.p ...

  8. 传智播客35期JavaEE工程师从基础到实战视频

    [No26]传智播客35期JavaEE工程师从基础到实战视频 就业班课程目录:      day01_html编程     day02_css编程     day03_javascript基础     ...

  9. 传智播客 php培训 mysql 刘道成 word 文档,传智播客 刘道成PHP视频教程 mysql 数据库视频教程...

    记得14年的时候有整理过这套课程,但是课程太多 今天却翻不到,所以在这里发一下吧. 4 ]0 {2 I. c- Z! u0 h6 J5 x传智播客出品 讲师 刘道成 Mysql 视频教程 mysql和 ...

最新文章

  1. php对长文章进行分页处理
  2. 算法周记(一)直接插入排序
  3. 锐捷升级最新版本出现虚拟网卡安装失败?
  4. HTTP之100-Continue
  5. Android ----中文Api 百度地图
  6. 史上最全的五大算法总结
  7. 苹果cms v8 漫漫看电影模板 自适应手机移动端
  8. 浅谈动态规划和分治、贪心算法的区别
  9. Python 杠上 Java、C/C++,赢面有几成?
  10. 数据科学包3-pandas快速入门2
  11. Oracle:ODP.NET Managed 小试牛刀
  12. centos du 命令使用
  13. mfc 使用flash控件注意事项
  14. python打开sql,Python打开Microsoft SQL Server MDF文件
  15. 翻遍互联网都找不到的解决方案,一行代码轻松实现 Gitbook 默认折叠左侧菜单效果
  16. SGU 244. Height, Bisector and Median
  17. 做网站需要用到哪些开发软件——心得分享
  18. java 小数乘法_java复习题69151-_人人文库网
  19. 应届生必看的职场建议
  20. 江湖云RFID电子标签在珠宝行业的应用

热门文章

  1. Netally公司的EtherScope nXG便携式网络分析测试仪
  2. 30张最具话题性照片
  3. 美通社企业新闻汇总 | 2019.2.18 | 《流浪地球》IMAX中国票房破三亿;阿迪达斯再推限定 UltraBOOST 19...
  4. 2021物联网国赛通用库开发——E卷
  5. 在Manjaro中Debtap将deb文件转换成pkg文件后,怎么解压生成的.pkg.tar.xz包?
  6. NVIC嵌套向量中断控制器
  7. 平衡电桥公式及如何求待测电阻值
  8. cocos creator 学习第一篇
  9. 联合开发MOBA游戏——王者荣耀的国际服《传说对决》
  10. PyScript:让Python在HTML中运行