1.软件开发
- 系统软件
- 应用软件
2. 人机交互的方式
- 图形化界面:简单直观
- 命令行方式:需要一个控制台,输入特定的指令
3. 常用的DOS命令
- dir:列出当前目录下的文件以及文件夹
- md:创建目录
- rd:删除目录
- cd:进入指定目录
- cd..:退回上一级目录
- del:删除文件
- exit:退出dos命令行
4.计算机编程语言的介绍
- 第一代语言:机器语言 二进制代码形式存在
- 第二代语言:汇编语言 使用助记符表示一条机器指令
- 第三代语言:高级语言 C面向过程、C++面向过程\面向对象 java:面向对象
5.java语言概述
-
Java语言是美国Sun公司(Stanford University Network)在1995年推出的计算机语言
Java之父:詹姆斯·高斯林(James Gosling)
2009年,Sun公司被甲骨文公司收购,所以我们现在访问oracle官网即可:https://www.oracle.com
-
1991年 Green项目,开发语言最初命名为Oak,1996年 发布jdk1.0,2004年,发布了jdk1.5里程碑式版本,2014年,发布了jdk1.8,是5.0以来变化最大的版本
-
java技术体系平台:JavaSE 标准版:支持面向桌面级应用的java平台 JavaEE 企业版:是为开发企业环境下的应用程序提供的一套解决方案 JavaME小型版:支持java程序运行在移动终端上的平台,加入了对移动终端的支持.
-
java在各个领域的应用:企业级应用、Android、大数据等
6. Java语言的主要特性
- 面向对象
- Java语言是健壮的
- 安全的
- 性能高
- 跨平台性
(1).java语言特点:
①面向对象:两个基本概念:类、对象 三大特性:封装继承 多态
②健壮性:吸收了C/C++语言的优点,去掉了影响其健壮性的部分,提供了相对安全的内存 管理机制和访问机制
③跨平台性:用过java语言编写的应用程序可以在不同的系统平台上运行(Write Once,Run Anywhere)
原理:只要在需要运行java应用程序的操作系统上,先安装一个java虚拟机,由JVM来负 责Java程序在系统中的运行.
7.Java语言的环境搭建
- JDK:(java Development Kit)Java开发工具包
- JRE:(Java Runtime Environment) java运行环境
- JDK=JRE+开发工具集
- JRE=JVM+JavaSE标准类库
- 官网下载安装:傻瓜式安装 直接下一步 要配置环境变量
- ①计算机-->右键 属性-->高级系统设置-->环境变量-->配置系统内变量 或者用户变量path-->把jdk所在的bin路径放在path上(每个配置之间用分号;隔开)-->确定
- ②为了安全起见 先起一个变量名JAVA_HOME:JDK bin所在的路径,(改掉path 换成%JAVA_HOME%\bin)PATH:%JAVA_HOME%\bin CLASSPATH:%JAVA_HOME%\lib
7.1第一个java程序 (HelloWorld)
①javac命令对java文件进行编译,java命令进行编译后的class文件执行
②在任意一个盘符下面新建一个以.java文件结尾的文本文件
③打开文件进行写代码
④进行ctrl+s保存 打开所在文件的目录下的cmd
8.注释
- 单行注释:// 注释文字
- 多行注释:/*注释文字*/
- 文档注释: /**注释文字*/
多行注释不能嵌套
9.Java关键字与保留字
- 关键字:是指被java语言赋予了特殊含义的单词。
-
关键字的特点:关键字的字母全部小写。
常用的代码编辑器对关键字都有高亮显示,比如现在我们能看到的public、class、static等。
保留字是现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要 避免使用这些保留字。例如:goto 、const
10 标识符
- Java对各种变量、方法和类等要素命名时候使用的字符序列称为标识符
- 标识符命名规则:
由字母、数字、下划线“_”、美元符号“$”组成,第一个字符不能是数字。
不能使用java中的关键字作为标识符。
标识符对大小写敏感(区分大小写)。
见名知意。
-
Java中标识符的命名约定: 小驼峰式命名:变量名、方法名 首字母小写,从第二个单词开 始每个单词的首字母大写。
大驼峰式命名:类名 每个单词的首字母都大写。
另外,标识符的命名最好可以做到见名知意
例如:username、studentNumber等。
11变量
-
变量:在程序运行过程中,其值可以发生改变的量。
从本质上讲,变量是内存中的一小块区域,其值可以在一定范围内变化。
-
声明变量:数据类型 变量名称 int age;先声明后使用
-
变量的赋值:变量名称=值 age=20;
-
声明和赋值变量:数据类型 变量名=初始化值 int age=20;
-
变量的作用域:一对{}之间有效,有初始化值
-
变量的分类:按数据类型分:Java是一个强类型语言,Java中的数据必须明确数据类型。在 Java中的数据类型包括基本数据类型和引用数据类型两种。
-
java的整型常量默认为int型,声明long类型常量必须在后面加上:"l"或者"L"
-
浮点型默认类型是Double
-
char只能表示一个字符
-
boolean 只能够取值为true 或false 不能取值为null
-
boolean类型适用于逻辑运算 一般用于流程控制
-
按声明的位置分:成员变量和局部变量
-
按类型分:整数类型:byte(1字节) short(2字节) int(4字节) long (8字节)
-
小数类型:Float(4字节) Double(8字节)
-
字符型:char(2字节)
-
布尔型:boolean(1字节)
-
使用变量注意事项:在同一对花括号中,变量名不能重复。
-
变量在使用之前,必须初始化(赋值)。
-
定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大 写)。因为整数默认是int类型,整数太大可能超出int范围。
-
定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大 写)。因为浮点数的默认类型是double, double的取值范围是大于float 的,类型不兼容。
-
类型转换:自动类型转换和强制类型转换
-
自动类型转换:当容量小的数据类型与容量大的数据类型做运算时候,容量小的 会自动转换为容量大的数据类型
-
byte short char做运算 自动提升为int
-
public class TestVeriable { public static void main(String[] args) { int i1 = 10; short s1 = 20; int i2 = i1 + s1; System.out.println(i2); float f1=12.9f; float f2=f1+i2; System.out.println(f2); long l=15l; float f3=l; System.out.println(f3); char c1=43; System.out.println(c1); char c2='a'; int i3=c2+1;; System.out.println(i3); } }
-
强制类型转换格式:容量大的转换为容量小的,会导致精度损失
-
数据类型 变量名 = (数据类型)值或者变量;
-
自动:double num=10; System.out.println(num);
-
强制:double num1 = 5.5; int num2 = (int) num1; System.out.println(num2);
-
char类型的数据转换为int类型是按照码表中对应的int值进行计算的。比如在ASCII码表中,'a'对应97。
-
int a = 'a'; System.out.println(a); // 将输出97
-
整数默认是int类型,byte、short和char类型数据参与运算均会自动转换为int类型。
-
byte b1 = 10;
byte b2 = 20;
byte b3 = b1 + b2;
// 第三行代码会报错,b1和b2会自动转换为int类型,计算结果为int,int赋值给byte需要强制类型转换。
// 修改为:
int num = b1 + b2;
// 或者:
byte b3 = (byte) (b1 + b2);int a = 1;
float b = 2.0f;
double c = a + b; -
boolean类型不能与其他基本数据类型相互转换。
-
字符串与基本数据类型之间做运算 只能是连接运算
-
int i=12; String str="hello"; String str2=str+i; System.out.println(str2);
12.进制
- 1.二进制:0,1 满二进一 以0b或者0B开头
- 十进制:0-9 满十进一
- 八进制:0-7 满八进一
- 十六进制:0-9及A-F 满16近1 以0x或者0X开头
- 2.原码、反码、补码:所有数字在在计算机底层都以二进制的形式存在,计算机以补码的形式保存所有的整数
- 正数的原码 反码 补码都相同
- 负数的补码是其反码加1
- 原码:直接将一个数值转换成二进制数
- 反码:对原码按位取反 只是最高位确定为1
13、运算符
算术运算符:+ - * / % ++ --
赋值运算符:= += -= *= /= %= instanceof
比较运算符(关系运算符):== != > < >= <=
逻辑运算符: &-逻辑与 &&-短路与 |逻辑或 ||-短路或 !-逻辑非 ^逻辑异或
位运算符
三元运算符
(1)算术运算符
public class TestAri {
public static void main(String[] args) {
/*
* 算术运算符
* */
int i = 10;
int j = i / 2;
double d = i / 2;
System.out.println(j);//5
System.out.println(d);//5.0
//取模 取余数
int i1 = i % 2;
System.out.println(i1);//0
int i4 = -12 % 5;
int i2 = 12 % (-5);
int i3 = -12 % (-5);
System.out.println(i4);//-2
System.out.println(i2);//2
System.out.println(i3);//-2
//前++: 后自增1 后做运算 后++:先做运算 后自增1
int number = 10;
int number1 = number++;//后++
System.out.println(number);//11
System.out.println(number1);//10
int number2 = 19;
int number4 = ++number2;//前++
System.out.println(number2);//20
System.out.println(number4);//20
//前--: 后自减1 后做运算 后--:先做运算 后自减1
int a=44;
int b=a--;
System.out.println(a);//43
System.out.println(b);//44
int c=66;
int f=--c;
System.out.println(c);//65
System.out.println(f);//65
}
}
(2)赋值运算符:
public class GetValue {
public static void main(String[] args) {
/*
* 赋值运算符
* */
int i=20;
i+=50;//i=i+50;
System.out.println(i);
byte b=10;
b=(byte) (b+6);//需要强转
b+=8;
System.out.println(b);//24
boolean b1=false;
//区分==和=区别
if (b1=true){
System.out.println("结果为真");//结果真
}else {
System.out.println("结果为假");
}
int i1=1;
i1*=0.1;
System.out.println(i1);//0
}
}
(3)关系运算符:
public class RelationTest {
public static void main(String[] args) {
/*
* 关系运算符都是布尔类型
* */
int a =5;
int b= 10;
System.out.println(a==b);//false
System.out.println(a!=b);//true
System.out.println(a>b);//false
System.out.println(a<b);//true
System.out.println(a<=b);//true
System.out.println(a>=b);//false
boolean flag=a>b;
System.out.println(flag);//false
}
}
(4)逻辑运算符:
public class TestLogic {
public static void main(String[] args) {
/*
* 逻辑运算符
* */
boolean b = true;
boolean b1 = false;
System.out.println(b & b1);//false
System.out.println(b && b1);//false
System.out.println(b | b1);//true
System.out.println(b || b1);//true
System.out.println(b ^ b1);//true
System.out.println(b & !b1);//true
//& 与 &&区别 : &左右都会进行判断是否true或false
// &&:当左端为false时 右端不进行判断
int i = 10;
if (b1 & (i++) > 0) {
System.out.println("真");
} else {
System.out.println("假");
}
System.out.println(i);//11
int i2 = 10;
if (b1 && (i2++) > 0) {
System.out.println("真");
} else {
System.out.println("假");
}
System.out.println(i2);//10
//| 与 ||区别: |:当左端为true时 右端还会做运算
// ||:当左边为true时 右边不做运算
int i3 = 10;
if (b | i3++ > 0) {
System.out.println("yes");
} else {
System.out.println("no");
}
System.out.println(i3);//11
int i4 = 10;
if (b || i3++ > 0) {
System.out.println("yes");
} else {
System.out.println("no");
}
System.out.println(i4);//10
int x = 1;
int y = 1;
if (x++ == 2 & ++y == 2) {
x = 7;
}
System.out.println("x=" + x + ",y=" + y);
int x1 = 1;
int y1 = 1;
if (x1++ == 2 && ++y1 == 2) {
x1 = 7;
}
System.out.println("x1=" + x1 + ",y1=" + y1);
int x2 = 1;
int y2 = 1;
if (x2++ == 2 | ++y2 == 2) {
x2 = 7;
}
System.out.println("x2=" + x2 + ",y1=" + y2);
int x3 = 1;
int y3 = 1;
if (x3++ == 2 || ++y3 == 2) {
x3 = 7;
}
System.out.println("x3=" + x3 + ",y3=" + y3);
}
}
(5)位运算符:
public class ExitBit {
public static void main(String[] args) {
/*
* 位运算符 << >> >>> & | ^ ~
* */
int i = 30;
System.out.println(i << 3);//240 30*2*2*2
System.out.println(i >> 2);//7 有符号右移
System.out.println(i >>> 2);//7
int j = -30;
System.out.println(j >> 2);//-8
System.out.println(j >>> 2);//1073741816
System.out.println(15 & 5);//5
System.out.println(15 | 5);//15
System.out.println(15 ^ 5);//10
System.out.println(~15);//-16
}
}
14.流程控制语句
- 顺序结构 分支结构(if-else switch-case) 循环结构(for while do-while);
- if-else三种结构
- if(条件表达式){
- 执行代码块;
- }
- if(条件表达式){
- 执行代码块;
- }else {
- 执行代码块2;
- }
- if(条件表达式){
- 执行代码块;
- }else if{
- 执行代码块2;
- }else{
- 执行代码块3;
- }
public class IfTest {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("请输入小明的成绩:");
int score = s.nextInt();
if (score==100){
System.out.println("奖励iPhone");
}else if (score>80&&score<=90){
System.out.println("奖励去游乐园");
}else if (score>=60&&score<=80){
System.out.println("奖励游戏机");
}else{
System.out.println("啥也没有!!");
}
}
}
- else结构是可选的
- 针对于条件表达式:
- 如果多个表达式之间是"互斥"关系(或者没有交集的关系),哪个判断和执行语句声明在上面和下面都没关系
- 如果多个表达式之间有交集关系,考虑实际情况 看看哪个在上面
- 如果多个表达式之间有包含关系,需要将范围小的声明放在范围大的上面,否则,范围小的没机会执行.
3.switch-case
public class Switch_caseTest {
public static void main(String[] args) {
int num=2;
switch (num){
case 0:
System.out.println("0");
case 1:
System.out.println("1");
case 2:
System.out.println("2");
case 3:
System.out.println("3");
default:
System.out.println("other");
}
}
}
根据switch中的表达式的值 一次匹配各个case 一旦匹配成功 则进入相应case结构中 调用执行语句 ,当调用执行语句之后 仍然会继续向下执行其他的case结构中的语句 直到遇到break或者switch-case末尾为止
public class Switch_caseTest {
public static void main(String[] args) {
int num=2;
switch (num){
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
default:
System.out.println("other");
}
}
}
break关键字可以使用在switch-case结构当中 表示一旦执行到此关键字 就跳出switch-case结构
public class Switch_caseTest1 {
public static void main(String[] args) {
int score=45;
switch (score/10){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("不及格");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("及格");
break;
}
}
}
如果switch-case结构中的多 个case执行语句相同,则可以合并
4.循环结构:
某些条件情况才 反复执行特定代码功能
循环语句分类:for while do-while
(1)for循环
public class ForTest {
public static void main(String[] args) {
/*
* 初始化条件 循环条件(布尔类型) 循环体 迭代条件
* */
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
int num = 1;
for (System.out.print('a'); num <= 3; System.out.print('c'), num++) {
System.out.print('b');
}
System.out.println();
//遍历100以内的偶数
int sum=0;//所有偶数的和
int count=0;//记录偶数的个数
for (int i = 1; i <= 100; i++) {
if (i%2==0) {
System.out.println(i);
sum+=i;
count++;
}
}
System.out.println(sum);
System.out.println("偶数的个数:"+count);
}
}
(2)while循环
①初始化条件;
while(②循环条件){
③循环体;
}
④迭代条件
public class WhileTest {
public static void main(String[] args) {
//100以内所有偶数
int i = 1;
while (i <= 100) {
if (i % 2 == 0) {
System.out.println(i);
}
i++;
}
}
}
注意:写while循环时候千万不要忘记写迭代条件 忘记了会出现死循环
for循环和while循环是可以相互转化的
while循环的初始化条件除了while循环还可以使用 作用域大,for循环的初始化条件只在for 循环范围内有效
(3)do-while循环:
①初始化条件;
do{
③循环体;
④迭代条件
}while(②循环条件);
do-while循环至少会执行一次循环体
public class DoWhileTest {
public static void main(String[] args) {
//遍历100以内的偶数 计算偶数的和 以及 偶数的个数
int i = 1;
int sum = 0;//总和
int count = 0;//个数
do {
if (i % 2 == 0) {
System.out.println(i);
sum += i;
count++;
}
i++;
} while (i <= 100);
System.out.println("总和" + sum);
System.out.println("个数" + count);
//do-while至少执行一次的情况
int number = 10;
while (number > 10) {
System.out.println("123123");
number--;
}
int number2 = 20;
do {
System.out.println("234234");
number2--;
} while (number2 > 20);
}
}
(4)死循环
①while(true){} ②for(;;){}
public class WhileTrueTest {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
int positiveNumber=0;//记录正数的个数
int nagativeNimber=0;//记录负数的个数
while (true){
int number = s.nextInt();
//判断number正负
if (number>0){
positiveNumber++;
}else if (number<0){
nagativeNimber++;
}else {
break;//执行到break结束循环
}
}
System.out.println("正数:"+positiveNumber);
System.out.println("负数:"+nagativeNimber);
}
}
(5)嵌套循环
将循环结构A声明在循环结构B的循环体中 。外层循环:循环结构B 内层循环:循环结构A
public class NestTest {
public static void main(String[] args) {
//嵌套循环
for (int j = 1; j <= 4; j++) {
for (int i = 1; i <= 6; i++) {
System.out.print("*");
}
System.out.println();
}
for (int i = 1; i <= 5; i++) {//控制行数
for (int j = 1; j <= i; j++) {//控制列数
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------");
for (int i=1;i<=4;i++){
for (int j=1;j<=5-i;j++){
System.out.print("*");
}
System.out.println();
}
System.out.println("=============================");
for (int i = 0; i < 5; i++) {
// 输出“-”
for (int j = 0; j < 4 - i; j++) {
System.out.print(" ");
}
// 输出“* ”
for (int k = 0; k < i + 1; k++) {
System.out.print("* ");
}
System.out.println();
}
// 下半部分
for (int i = 0; i < 4; i++) {
for (int j = 0; j < i + 1; j++) {
System.out.print(" ");
}
for (int k = 0; k < 4 - i; k++) {
System.out.print("* ");
}
System.out.println();
}
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
// 分三个大部分 上中下
for (int i = 0, k = 0; i < 14; i++) {// 打印行
// 上部分 上分为 四个部分
if (i < 3) {
for (int j = 0; j < 5 - 2 * i; j++) {// 1、空心
System.out.print(" ");
}
if (i == 2) {// 2、*
for (int j = 0; j < 6 + 4 * i - 1; j++) {
System.out.print("*");
}
for (int j = 0; j < 7 - 4 * i + 2; j++) {// 3、空心
System.out.print(" ");
}
for (int j = 0; j < 6 + 4 * i - 1; j++) {// 4、*
System.out.print("*");
}
} else {
for (int j = 0; j < 6 + 4 * i; j++) {// 2、*
System.out.print("*");
}
for (int j = 0; j < 7 - 4 * i; j++) {// 3、空心
System.out.print(" ");
}
for (int j = 0; j < 6 + 4 * i; j++) {// 4、*
System.out.print("*");
}
}
} else if (i < 6) {// 中间
for (int j = 0; j < 29; j++) {
System.out.print("*");
}
} else {// 下部分 6
if (i == 13) {
for (int j = 0; j < 2 * (i - 6); j++) {// 打印空格
System.out.print(" ");
}
System.out.print("*");
} else {
for (int j = 0; j < 2 * (i - 6) + 1; j++) {// 打印空格
System.out.print(" ");
}
for (int j = 1; j < 28 - 4 * k; j++) {
System.out.print("*");
}
k++;
}
}
System.out.println();// 换行
}
}
}
内层循环结构遍历一遍 相当于外层循环执行一次循环体
(5)break continue使用:
break:使用在switch-case和循环结构中,在循环结构中执行到break 结束循环
continue:使用在循环结构中 结束档次循环
break continue:后面不能有执行语句
public class BreakContinueTest {
public static void main(String[] args) {
for (int i=1;i<=10;i++){
if (i%4==0){
// break;//123
continue;//123567910
// System.out.println("123");
}
System.out.print(i);
}
System.out.println();
label: for (int i=1;i<=4;i++){
for (int j=1;j<=10;j++){
if (j%4==0){
//break;//默认跳出此关键字最近一层的循环
// continue;
// break label;//结束指定标识的循环结构
continue label;
}
System.out.print(j);
}
System.out.println();
}
}
}
15.Scanner:从键盘获取不同类型的变量
1.使用步骤:导包 import java.util.Scanner;
Scanner实例化:Sc anner s=new Scanner(System.in);
调用Scanner类的相关方法 来获取指定类型的相关变量
import java.util.Scanner;
class ScannerTest{
public static void main(String[] args){
//从键盘获取不同类型的变量 Scanner
Scanner s=new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name=s.nextLine();
System.out.println(name);
System.out.println("请输入你的年龄:");
int age=s.nextInt();
System.out.println(age);
System.out.println("请输入你的体重:");
double weight=s.nextDouble();
System.out.println(weight);
System.out.println("你好看吗?(true/false)");
boolean love=s.nextBoolean();
System.out.println(love);
//对于char型的获取 Scanner没有提供相关的方法s
System.out.println("请输入你的性别?(男/女)");
String gender=s.next();
char genderChar=gender.charAt(0);//获取索引为0位置上的字符
}
}
注意:需要根据相应的方法 来输入指定类型的值 ,如果输入的类型与要求的类型不匹配时 会报InputMisMatchExcetion异常 导致程序无法执行
16.随机数:获取10-99之间的数
double value=(int)(Math.random()*90+10); [0.0,1.0)-->[0.0,90.0)-->[10.0,100.0)-->[10,99]
公式:[a,b] (int)(Math.random()*(b-a+1)+a);
17.数组
1.数组的概述:多个相同类型数据按一定顺序排列的集合 并使用一个名字命名,并通过编号的方式对数据进行管理
2.数组的特点:有序排列的
数组属于引用类型的变量,数组的元素 既可以是基本数据类型 也可以是引用数据类型
创建数组对象会在内存中开辟一整块连续的空间
数组的长度一旦确定不能修改
3.数组的分类:一维数组 二维数组
按照数组元素的类型:基本数据类型元素的数组 引用数据类型的数组
4.数组的声明和初始化
①静态初始化:int[] id=new int[]{1,2,3};数组的初始化和数组元素的赋值操作同时进行
②动态初始化:String[] name=new String[5];数组的初始化和数组元素的赋值操作分开进行
5.数组的索引从0开始 到数组长度-1结束
数组长度使用length属性
数组的遍历使用循环
6.数组元素的默认初始化值:
①整数类型:0 ②浮点类型:0.0 ③char类型:0 ④布尔类型:false ⑤:引用类型:null
7.数组的内存解析
public class ArrayTest {
public static void main(String[] args) {
//一维数组使用
/*
* 一维数组的声明 初始化
* 如何调用数组指定位置的元素
* 如何获取数组的长度
* 遍历数组
* 数组元素的默认初始化值
* 数组的内存解析
* */
//1.一维数组的声明 初始化
int num;//声明
num = 10;//初始化
int id = 333;//声明和初始化
int[] number; 声明
//静态初始化 数组的初始化和数组元素的赋值操作同时进行
number = new int[]{1, 2, 3};
//动态初始化 数组的初始化和数组元素的赋值操作分开进行
String[] name = new String[5];
//2.如何调用数组指定位置的元素
//数组的索引从0开始 到数组长度-1结束
name[0] = "你好";
name[1] = "天气";
name[2] = "大大";
name[3] = "小小";
name[4] = "游戏";
//3.如何获
// 取数组的长度
System.out.println(name.length);
//4.遍历数组
for (int i = 0; i < name.length; i++) {
System.out.println(name[i]);
}
//5.数组元素的默认初始化值
int[] arr = new int[3];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
float[] f = new float[4];
for (int i = 0; i < f.length; i++) {
System.out.println(f[i]);
}
//6.数组的内存解析
}
}
8.二维数组:
public class ArrayTest3 {
public static void main(String[] args) {
/*
* 二维数组的声明 初始化
* 如何调用数组指定位置的元素
* 如何获取数组的长度
* 遍历数组
* 数组元素的默认初始化值
* 数组的内存解析
* */
//二维数组的声明 初始化
int[][] arr1=new int[][]{{2,3},{4,5,6},{6,7,8}};
String[][] arr2=new String[3][2];
String[][] arr3=new String[3][];
//2.如何调用数组指定位置的元素
System.out.println(arr1[0][0]);//2
System.out.println(arr2[1][1]);//null
arr3[1]=new String[3];
arr3[1][0]="dada";
System.out.println(arr3[1][0]);//dada
//3.如何获取数组的长度
System.out.println(arr1.length);//3
System.out.println(arr1[1].length);//3
//4.遍历数组
for (int i=0;i< arr1.length;i++){
for (int j=0;j<arr1[i].length;j++){
System.out.print(arr1[i][j]+" ");
}
System.out.println();
}
//5.数组元素的默认初始化值
int[][] array=new int[3][3];
System.out.println(array[0]);//[I@14ae5a5
System.out.println(array[0][1]);///0
int[][] array1=new int[3][];
System.out.println(array1[0]);
}
}
十八:面向对象
1.java类和类的成员:属性、方法、构造器、代码块、内部类
2.面向对象的三大特征:封装 继承 多态
3.其他关键字:super this import package final abstact
4.面向过程与面向对象:①面向过程:强调的是功能行为,以函数为最小单位 考虑怎么做
②面向对象:强调了具备功能的对象,以类/对象为最小单位 考虑谁 来做
5.类:是一类实务的描述 抽象的概念上的定义
对象:实际存在的事物
属性:对应类中的成员变量
行为:对应类中的成员方法
public class Person {
public static void main(String[] args) {
/*测试类*/
//创建对象
Per p=new Per();
//调用对象的属性方法 对象.属性
p.age=18;
p.name="lala";
p.isMale=true;
System.out.println(p.age);
//调用方法 对象.方法
p.eat();
p.sleep();
p.talk("Chinese");
System.out.println("--------------------------------");
//创建了一个类的多个对象 则每个对象都独立的拥有一套类的属性
Per p1=new Per();
System.out.println(p1.age);//0
Per p2=p;
System.out.println(p.age);//18
}
}
class Per{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("吃饭,,,,");
}
public void sleep(){
System.out.println("睡觉,,,,");
}
public void talk(String language){
System.out.println("说话,,,,");
}
}
6. 内存解析
7.创建对象:类名 变量名=new 类名();
调用属性:对象名(变量名) .属性/方法
8.属性(成员变量)VS局部变量:
①:相同点:定义变量的格式:数据类型 变量名=变量值; 先声明后使用;变量都有其对应 的作用域
②:不同点:在类中声明的位置不同:成员变量直接定义在类的一对{}内
局部变量声明的方法内 方法形参 代码块内 构造器形 参 构造器内的变量
权限修饰符的不同:成员变量:可以声明属性指定权限 使用权限修饰符
局部变量:不可以使用权限修饰符
常用的权限修饰符:private public default protected
默认初始化的不同:成员变量:类的属性 根据其类型 都有默认初始化值
整型:(byte short int long ):0
浮点型:(float double):0.0
字符型:(char):0/ \u0000
布尔型:(boolean):false
引用数据类型:(类 数组 接口):null
局部变量:没有默认初始化值 调用局部变量之前一定要 显示赋值 形参在调用时 也要赋值
在内存中加载的位置不同:成员变量加载在堆内存中(非static)
局部变量加载在栈内存中
8.方法:描述类应该具有的功能
方法的声明:权限修饰符 返回值类型 方法名(形参列表){
方法体;
}
9.返回值类型:如果方法有返回值 则必须在方法声明时 指定返回值类型 同时 方法中需要使用 return关键字返回指定类型的变量或常量; “return 数据”;
如果方法没有返回值 使用void来表示 通常没有返回值夫人方法中不需要return 如 果使用 只能 “return”;表示结束方法的意思
return后面不能用执行语句
10形参列表:方法可以声明0个,1个或多个形参
格式:数据类型1 形参1,数据类型2 形参2,.....
11.return关键字的使用:①使用范围:使用在方法体中
②作用:结束方法
③针对有返回值类型的方法 使用"return 数据" 方法返回所需要的数据
④return后面不能用执行语句
12.方法的使用:可以调用当前类的属性或方法
特殊的:方法A中调用了方法A称为递归方法
方法中不可以定义方法
13.虚拟机栈:将局部变量存储在栈结构中
堆:将new出来的结构(比如:数组 对象)加载在堆空间中 对象的属性非static加载在堆空间中
方法区:类的加载信息 常量池 静态域
14.万事万物皆对象:我们将功能结构封装到类中 通过类的实例化 来调用具体的功能结构
15匿名对象:创建对象没有显示的赋给一个变量名 称为匿名对象
特征:只能使用一次
16.方法的重载:方法名相同参数列表不同 跟返回值类型 访问修饰符 形参变量名无关
17.可变个数形参;jdk5新增 格式:数据类型...变量名
当调用可变个数形参时 传入的参数可以是0个,1个,2个
可变个数形参方法与本类中方法名相同 形参的不同构成方法之间的重载
可变个数形参方法与本类中方法名相同 形参类型也相同的数组之间不构成载 二者不能共存
可变个数形参方法的形参中 必须声明在末尾
可变个数形参方法 的形参中 最多只能声明一个可变形参
18.方法参数的值传递机制:
①:如果变量是基本数据类型 此时赋值的是变量有保存的数据值
②:如果变量是基本引用数据类型 此时赋值的是变量有保存的地址值
19.形参:定义在方法声明时小括号内的参数
实参:方法调用时 实际传递形参的数据
20.递归方法:
/*递归*/
public class RecursionTest {
public static void main(String[] args) {
//1-100之间所以自然数的和
RecursionTest recursionTest=new RecursionTest();
System.out.println(recursionTest.getSum(100));
}
public int getSum(int n){
if (n==1){
return 1;
}else {
return n+getSum(n-1);
}
}
}
十九、面向对象的特征之一:封装与隐藏
1.高内聚:类的内部数据操作细节自己完成 不允许外界干涉
低耦合:仅对外暴露少量的方法用于使用
public class AnimalTest {
public static void main(String[] args) {
Animal a = new Animal();
a.name = "lala";
a.age = 3;
// a.legs = 4;
a.show();
a.setLegs(8);
a.show();
}
}
class Animal {
String name;
int age;
private int legs;
public void setLegs(int l) {
if (l >= 0 && l % 2 == 0) {
legs = l;
} else {
legs = 0;
}
}
public void eat() {
System.out.println("chi");
}
public void show() {
System.out.println("name:" + name + ",age:" + age + ",legs:" + legs);
}
}
封装性的体现:将类的属性私有化 同时 提供公共的方法来获取(getXX)和设置(setXX)属性的值
封装性的体现:需要权限修饰符来配合
4种权限修饰符可以用来修饰类及类的内部结构:属性 方法 构造器 内部类
修饰类的话只能使用缺省 public
2.构造器使用:①如果没有显示的定义类的构造器 则系统默认提供一个空参的构造器
②定义构造器格式:权限修饰符 类名(形参列表){ }
③一个类中定义多个构造器 彼此构成重载
④一旦显示的定义了类的构造器之后 系统不在提供默认的空参构造器
⑤一个类中 至少会有一个构造器
3.总结:属性赋值的先后顺序
①默认初始化
②显示初始化
③构造器赋值
④通过"对象.方法或对象.属性"方式
4.this的使用:①this可以用来修饰属性、方法、构造器
②this理解为当前对象
③在类的方法中 我们可以使用"this.属性"或"this.方法"调用当前对象属性或方法 但 通常情况下 我们可以选择省略this,特殊情况下 如果方法的形参和类的属性同名 时 我们必须显示的使用this变量 表示此变量是属性而非形参
this调用构造器:①在类的构造器中 可以显示的使用 "this(形参列表)"方式,调用本类中指定的其 他构造器
②构造器中不能"this(形参列表)"调自己
③如果一个类中有n个构造器 则最多有n-1个构造器使用了this(形参列表)
④规定:this(形参列表) 必须声明在当前构造器的首行
⑤构造器内部 最多只能声明一个 this(形参列表) 用来调用其他构造器
5.package关键字的作用:①使用package声明类或接口多属的包 声明在源文件的首行
②遵循标识符命名规则 见名知意
③每"."一次代表一次文件目录
④同一个包下不能命名相同名字的接口或类 不同的包下可以
import关键字使用:①在源文件中显示的使用import结构 导入指定包下的类 接口
②声明在包和类之间
③如果需要导入多个结构 则并列写出即可
④可以使用“XXX.*”的方式 表示可以导入xxx下的所有结构
⑤如果使用的类是java.lang包下定义的 则可省略import结构
⑥如果使用的类或接口是本包下定义的 则可省略import结构
⑦如果在源文件使用了不同包下的同名的类 则必须至少有一个类需要以全类 名的方式展示
⑧使用"xxx.*"方式表明可以调用xxx包下的所有结构 但如果使用的是xxx子包 下的结构 则人需要显示导入
⑨import static:导入指定类或接口中的静态结构
6.javaBean:①类是公共的 ②一个无参的构造器 ③属性 有对应的get set方法
二十、面向对象的特征之二:继承
1.继承的好处:①减少了代码的冗余 提高了代码的复用性
②便于功能的扩展
③为之后的多态性提供了前提
2.继承性的格式:class A extends classB{ }
A:子类 派生类 subclass
B:超类 基类 superclass
体现:①一旦子类A继承父类B以后,子类A就获取了父类B中声明的结构 属性 方法
②特别的 父类中声明私有的属性或方法 子类继承父类之后 仍然认为获取了父类中 私有的结构 只因为封装性的影响 使得子类不得直接调用父类的结构而已
③子类继承父类之后 还可以定义自己的属性或方法 实现了功能的扩展
3.java中关于继承性的规定:①一个类可以被多个子类继承
②一个类只能有一个父类
③java中的类的单继承性:一个类只能有一个父类
⑤子类直接继承的父类 称为:直接继承
子类间接继承的父类 称为 间接继承
⑥子类继承父类之后 就获取了直接父类以及所有间接父类中 声明的属性或方法
4.如果没有显示声明一个类的父类 则此类继承于java.long.Object类
所有java类(除java.long.Object类)都直接或间接继承于java.long.Object类
所有java类都具有java.long.Object类声明的功能
5.方法的重写: ①子类继承父类以后 可以对父类中同名同参数的方法 进行覆盖操作
②重写以后,当创建子类对象以后 通过子类对象调用父类中的同名同参数的 方法时 实际执行的是子类重写父类的方法
重写的规定:①子类重写的方法名和参数列表与父类被重写的方法名和参数列表相同
②子类重写的权限修饰符不小于父类被重写的方法的权限修饰符 特殊情况, 子类不能重写父类中声明为private权限的方法
③返回值类型:父类被重写的方法的返回值类型是void 则子类重写的方法的返 回值类型只能是void
父类被重写的方法的返回值类型是A类型,则子类重写的方法 的返回值类型A类或者A的子类
父类被重写的方法的返回值类型是基本数据类型 则子类方法的 返回值类型必须是相同的基本数据类型
④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
⑤子类和父类中同名同参数的要么都声明为非static 要么都是static(不是重写)
6.super关键字的作用:①super理解为:父类的
②super可以用来调用属性 方法 构造器
③super的使用;可以在子类的方法或者构造器中 通过使用"super.属 性"或"super.方法"的方式 显示的调用父类中声明的属性或方法 但是 通常情况下 习惯省略"super",特殊情况下 当子类和父类中定义了 同名的属性时 想要在子类中调用父类中声明的属性 则必须显示的 使用"super.属性"的方式 表明调用的是父类中声明的属性,特殊情 况当子类重写额父类的方法以后 想在子类的方法中调用父类中被重 写的方法时 则必须显示的使用"super"方法 表明调用的是父类中被 重写的方法
super调用构造器:①可在子类的构造器中显示的使用"super(形参列表)"方式 调用父类中 声明的指定构造器
②"super(形参列表)"的使用,必须声明在子类构造器首行
③在类的构造器中 针对于"this(形参列表)"或"super(形参列表)"只能二 选一 不能同时存在
④在构造器首行 我们没显示声明"this(形参列表)"或"super(形参列 表)",则默认调用的是父类中空参的构造器super();
⑤在类的多个构造器中 至少有一个类的构造器使用了"super(形参列 表)" 调用了父类中的构造器
7.子类对象实例化过程:①从结果上看:子类继承父类之后 就获取了父类中声明的属性或方法 创 建子类对象 在堆空间中就回家再所有父类的声明的属性
②从过程上看:通过子类构造器创建子类对象时 一定会直接或间接调用 父类的构造器 进而调用父类的父类的构造器...,直到调用了 java.lang.Object类中的空参构造器 正因为加载过所有父类的结构 所 有才可以看到内存中有父类中的结构 子类对象才可以考虑调用
明确:虽然创建子类对象时 调用了父类的构造器 但一直以来就创建过一个对象 即为new的子 类对象
二一:面向对象特征制之三:多态性
1.理解多态性:一个事物的多种形态
2.对象的多态性:父类引用指向子类对象
3.多态的使用:虚拟方法调用 有了对象的多态性之后 我们在编译期 只能调用父类中声明的 方法 但是在运行期 实际执行的是子类重写父类的方法
总结:编译 看左边 运行 看右边
4.多态使用前提:类的继承关系 方法的重写
5.对象的多态性 只用于方法 不用于属性
6.instanceof操作符
①有了对象的方法多态性之后,内存中实际是加载了子类特有的属性和方法的 但是由 于变量声明为父类类型 导致编译时 只能调用父类中声明的属性或方法 子类特有的属 性和方法不能调用
②如果调用子类特有的属性和方法
向下转型:使用强制类型转换符 使用向下转型可能出现异常
③a instanceof A:判断对象a是否是A的实例,如果是:返回true 如果不是:返回false
使用情况:为了避免向下转型时出现ClassCastException异常:在向下转型之前,先 进行instanceof判断,一旦返回true 就进行向下转型,如果返回false 不进 行向下转型
如果a instanceof A返回true,则a instanceof B也返回true 其中B是A的父类
public class Person {
String name;
int age;
int id = 1001;
public void eat(){
System.out.println("人:吃饭");
}
public void walk(){
System.out.println("人:走路");
}
}
public class Man extends Person{
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
public class Woman extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println("女人喜欢购物");
}
public void eat(){
System.out.println("女人少吃,为了减肥");
}
public void walk(){
System.out.println("女人窈窕的走路");
}
}
public class PersonTest {
public static void main(String[] args) {
//多态性
Person p = new Person();
p.eat();
Man m = new Man();
m.eat();
m.age = 7;
m.earnMoney();
//对象多态性 父类引用指向子类对象
Person p1 = new Man();
//多态使用 当调用子父类同名同参数方法时 实际执行的是子类重写父类的方法 虚拟方法调用
p1.eat();
p1.walk();
// Person p2=new Woman();
//有了对象的多态性以后 内存中实际上是加载了子类特有的属性和方法 但是由于变量声明为父类类型 导致编译时 只能调用父类中声明的属性和方法 子类特有的属性和方法不能调用
//向下转型
Man m1 = (Man) p1;
m1.earnMoney();
System.out.println(m1.isSmoking = true);
//使用强转时可能出现异常
// Woman w = (Woman) p1;
// w.goShopping();
/*instanceof
* a instanceof A:判断a是否是类A的实例 如果是 返回true 不是 返回false
* */
if (p1 instanceof Woman) {
Woman w = (Woman) p1;
w.goShopping();
System.out.println("Woman");
}
if (p1 instanceof Man) {
Man w = (Man) p1;
w.earnMoney();
System.out.println("man");
}
//练习一 编译时通过 运行时不通过
// Person p3=new Woman();
// Man m2=(Man) p3;
// Object o = new Date();
// String s = (String) o;
}
}
7.Object类
(1).Object类是所有java类的根父类
(2).如果在类的声明中未使用extends关键字知名父类 则默认父类java.lang.Object
(3).Object类中的功能 属性 方法都具有通用性
(4).Object类只声明了一个空参的构造器 没有属性
方法:equals()\toString()\getClass()\hashCode()\clone()\finalize()\wait()\notify()\notifyAll()
8.==的使用:==是运算符
①可以使用在基本数据类型变量和引用类型变量中
②如果比较的基本数据类型变量 比较两个变量保存的数据是否相等
如果比较的引用类型变量 比较的是两个对象地址值是否相同 即两个引用是否指向一个实体
equals方法作用:
①是一个方法 而非运算符 只能用于引用数据类型
②Object类中equals定义:public boolean equals(Object obj){
return (this==obj);
}
说明:Object类中定义的equals()和==作用相同,比较两个对象的地址值是否相同 即两个引用 是否指向一个实体
③像String Date File 包装类等,都重写Object类中equals方法 重写以后 比较的不是两个引用 地址值是否相同 而是比较两个对象的"实体内容"是否相同
④自定义类如果使用equals()的话,也通常比较两个对象的"实体内容"是否相同 name主要对 Object类中的equals()方法进行重写
重写原则:比较两个对象的实体内容是否相同
public class OrderTest {
public static void main(String[] args) {
Order order1=new Order(1,"A");
Order order2=new Order(1,"B");
System.out.println(order1.equals(order2));
Order order3=new Order(1,"B");
System.out.println(order2.equals(order3));
}
}
class Order {
private int orderId;
private String orderName;
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Order(int orderId, String orderName) {
this.orderId = orderId;
this.orderName = orderName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof Object) {
Order order = (Order) o;
return this.orderId == order.orderId && this.orderName.equals(order.orderName);
}
return false;
}
}
9.toString
①当输出一个对象引用时 实际上就是调用当前对象的提String();
②Object类中toString定义:public String toString(){
return getClass.getName()+"@"+Integer.toHexString(hashCCode);
}
③像String Date File 包装类等都重写Object类中toString方法 使得在调用toString()方法返回时"实 体内容"
④自定义类也可以重写toString()方法 当调用此方法时 返回对象的"实体内容"
10.包装类的使用
①基本数据类型----》包装类
int i = 10;
Integer in =new Integer(i);
②包装类----> 基本数据类型
Integer in =new Integer(12);
int i1=in.intValue();
③JDK5.0新特性,自动装箱 自动拆箱
自动装箱:int num = 10; Integer in1 =num;
自动拆箱 int num3=in1;
④基本数据类型与包装类和String转换:调用String重载的valueof()
int num1 = 10;
String s= String.valueof(num1);
⑤String--->基本数据类型 包装类
String s="123";
int i = Integer.parseInt(s);
二十一.static
1.static:静态的
static可以用来修饰属性 方法 代码块 内部类
使用static修饰属性 静态变量(类变量):
属性按照是否是static修饰的又分为静态属性和非静态属性(实例变量)
实例变量:创建了类的多个对象 每个对象都独立的拥有一套类的非静态属性,当修改其中 一个对象中的的非静态属性时 不会导致其他对象中同样属性值得修改
静态变量:创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静 态变量时,会导致其他对象调用此静态变量时 是修改以后的
static修饰属性的其他说明:①静态变量随着类的加载而加载
②静态变量的加载要早于对象的创建
③由于类加载一次 静态变量在内存中也只会存在一份 存在方 法区的静态域中
④ 类变量 实例变量
类 yes no
对象 yes yes
静态属性举例:System.out; Math.PI;
2. 使用static修饰方法:静态方法:①随着类的加载而加载 可以通过"类.静态方法"的方式进行 调用
② 静态方法 非静态方法
类 yes no
对象 yes no
③静态方法中只能调用静态的方法或属性
非静态方法中 既可以调用非静态的方法或属性 可以调用 静态的方法或属性
3.static注意点:在静态的方法内 不能使用this关键字 super关键字
关于静态属性和静态方法的使用 可以根据声明周期角度理解
4.如何确定一个属性或方法要声明为static的?
属性可以被多个对象共享的 不会随着对象的不同而不同 类中的常量池也常常声明为static
操作静态属性的方法 通常设置为static 工具类中的方法 习惯上声明为static 比如:Math, Arrays、Collections
5.static内存解析:
6.单例(Singleton)设计模式
public class SingletonTest {
Bank bank1=Bank.getInstance();
}
//饿汉式
class Bank{
//私有化构造器
private Bank(){
}
//内部创建类对象
private static Bank instance =new Bank();
//提供供的静态方法
public static Bank getInstance(){
return instance;
}
}
//懒汉式
public class SingletonTest2 {
public static void main(String[] args) {
Order o1=Order.getInstance();
Order o2=Order.getInstance();
System.out.println(o1==o2);
}
}
class Order {
// 1.私有化类的构造器
private Order() {
}
//2.声明当前类对象
private static Order instance = null;
//声明public static 的返回当前类对象的方法
public static Order getInstance() {
if (instance==null){
instance = new Order();
}
return instance;
}
}
区分懒汉式和饿汉式:
饿汉式:坏处:加载时间过长 好处:线程安全
懒汉式:好处:延迟对象的创建 坏处:线程不安全
单例设计模式应用场景:①网站计数器 ②应用程序的日志应用 ③数据库连接池等
7.main()方法使用说明:①main()方法作为程序的入口 ②main()方法也是普通的静态方法
③main()方法可以作为与控制台交互的方式
8.代码块:①作用:用来初始化类 对象
②代码块中如果有修饰的话 只能使用static
③分类:静态代码块vs非静态代码块
静态代码块:内部可以有输出语句
随着类的加载而执行 而且只执行一次
初始化类的信息 如果一个类中定义了多个代码块,则按照声明的顺序 先后执行
静态代码块的执行要优先于非静态代码块的执行
静态代码块内只能调用静态的属性 静态的方法 不能调用非静态的结构
非静态代码块:内部可以有输出语句
随着对象的创建而执行
每创建一个对象 就会执行一次非静态代码块
作用:可以在创建对象时 对对象的属性等进行初始化
如果一个类中定义了多个非静态代码块 则按照声明的顺序执行
非静态代码块内可以调用静态的属性 静态的方法 或非静态的属性 非静态的方法
9.final关键字:
①final可以用来修饰结构 类 方法 变量
②final用来修饰一个类 :不能被继承 比如:String System StringBuffer
③final用来修饰方法 表明此方法不能被重写 比如Object的getClass()
④final修饰变量:此时的变量称为常量 不能改变
final修饰属性:可以考虑赋值的范围有:显示初始化 代码块初始化 构造器初始化
final修饰局部变量:使用final修饰形参时 表明此形参是一个常量 当遇到此方法时 给常量形参赋一个实参 一旦赋值以后 就只能在方法体内使用形参 但不进行冲洗赋值
⑤static final:用来修饰属性 全局常量
二十二 、抽象类与抽象方法
1.abstract:关键字的使用:①abstract:抽象的
②abstract可以用来修饰的结构 类 方法
③abstract修饰类 抽象类 此类不能实例化 抽象类一定有构造器 便 于子类实例化时调用
④开发中 都会提供抽象类的子类 让子类对象实例化 完成相关的 操作
abstract修饰方法:抽象方法:①抽象方法只有方法的声明 没有方法体
②包含抽象方法的类 一定是抽象类 反之 抽象类可以没有抽象 方法
③若子类重写父类中的所有的抽象方法后 此类方可实例化
若子类没有重写父类中所有的抽象方法 则子类也是一个抽 象类 需要abstract修饰
abstract注意点:①abstract不能用来修饰属性 构造器等结构
②abstract不能用来修饰私有方法 静态方法 final的方法 final的类
二十三、接口
1.接口的使用interface定义
2.java中 接口和类是并列的两个结构
3.如何定义接口 定义接口的成员:①JDK7之前 只能定义全局常量和抽象方法 全局常量: public static final的可以省略不写
抽象方法 public abstract
②jdk8:除了定义定义全局常量和抽象方法之外 还可 以定义静态方法 默认方法 接口中定义的静态方法 只 能通过接口类调用
③接口不能定义构造器 不能实例化
④开发中 接口通过让类实现(implements)的方式使用 如果实现类覆盖了接口中的所有抽象方法 则此实现 类就可以实例化 如果实现类没有覆盖接口中所有的 抽象方法 则此实现类仍为一个抽象类
⑤java类可以实现多个接口-->弥补了java单继承的局 限性 格式:class A extends B implements c,D....
⑥接口与接口之间可以多继承
⑦接口的具体使用:体现多态性
⑧接口实际上看做是一种规范
⑨通过 实现类额对象 可以直接调用接口中的默认方 法如果实现类重写了接口中的默认方法 调用时 仍然 调用的是重写的方法
⑩如果子类(或实现类)继承的父类实现的接口中声明了 同名同参数的方法 那么子类在没有重写此方法的情 况下 默认调用的是父类中的同名同参数的方法 类 优先原则
二十四、内部类
1.java中 允许将一个类A声明在另一个类B中 则类A就是内部类 类B称为外部类
内部类的分类 成员内部类VS局部内部类(方法体 代码块 构造器内)
成员内部类:①作为外部类的成员 调用外部类的结构 可以被static修饰 可以被4中不同的 权限修饰符修饰
②作为一个类:类内可以定义属性 方法 构造器等
可以被final修饰 表示此类不能被继承 不使用final可以被继承
可以被abstract修饰
二十五、异常
1.error:java虚拟机无法解决的严重问题 比如JVM系统内部错误 资源耗尽等情况,比如StackOverflowError和OOM 一般不编写针对性的代码
2.Exception:编译期异常 运行期异常
3.异常处理机制
try catch finally throws+异常类型
public class ExceptionTest1 {
public static void main(String[] args) {
/*
* 异常
* */
int[] arr = new int[3];
// arr=null;
// System.out.println(arr[3]);//Exception in thread "main" java.lang.NullPointerException
// System.out.println(arr[3]);//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
// Object o= new Date();
// String s=(String) o;
// System.out.println(s);//Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String
// String s="123";
// s="aa";
// int i = Integer.parseInt(s);
// System.out.println(i);//Exception in thread "main" java.lang.NumberFormatException: For input string: "aa"
// Scanner scan=new Scanner(System.in);
// int i = scan.nextInt();
// System.out.println(i);//Exception in thread "main" java.util.InputMismatchException
// int i=10;
// int b=0;
// System.out.println(i/b);//public class ArithmeticException extends RuntimeException {
// File file = new File("hello.txt");
// FileInputStream fileInputStream = new FileInputStream(file);
// int read = fileInputStream.read();
// while (read == -1) {
// System.out.print((char) read);
// }
// fileInputStream.close();
}
}
public class ExceptionTest2 {
public static void main(String[] args) {
/*
* try catch finally
* */
String s="123";
s="aa";
try {
int i = Integer.parseInt(s);
System.out.println(i);
} catch (NumberFormatException e) {
//String getMessage()
// 1. System.out.println(e.getMessage());//For input string: "aa"
// System.out.println("出现类转换异常");
// 2. e.printStackTrace();
} finally {
System.out.println("--------");
}
try {
File file = new File("hello.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int read = fileInputStream.read();
while (read == -1) {
System.out.print((char) read);
}
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
public class ExceptionTest3 {
public static void main(String[] args) {
/*throws*/
try {
method2();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
public static void method2()throws IOException{
method1();
}
public static void method1()throws IOException{
File file = new File("hello.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int read = fileInputStream.read();
while (read == -1) {
System.out.print((char) read);
read=fileInputStream.read();
}
fileInputStream.close();
}
}