Java基础知识

发布时间:2024年01月12日

Java语言的特点

*跨平台性 ??面向对象 (多继承,指针) 健壮性(垃圾回收,异常处理) 多线程

Java类和类之间的关系

? ? ? ? 继承 ? 关联 ? 依赖

Java面向对象的四个特征(特性)

? ? ? ? 继承 ? 封装 ? 多态 ? (抽象)

JVM (虚拟机):java virtual machine

?内存中开辟一块空间 源文件编译成计算机能识别的字节码文件

JRE? java runtime environment 运行环境 ???JRE里面包含JVM

运行别人写好的java程序

JDK? java development kit 开发工具包 ???JDK里面包含JRE

??????? 开发时需要用到的工具

配置环境变量

Win+r 输入cmd指令 开启一个doc窗口

切换盘符 盘符名:回车 ??cd..退一层文件夹 ?cd 文件名(* ? #) 进入文件夹 ?????

配置环境变量 添加jdk/bin到环境变量 doc窗口输入javac

配置path?? 让工具可以在任何的位置都可以用

配置 classPath 不管源文件在哪 生成的class文件都统一的存储在配置的目录下

编译Javac Test.java(源代码文件)? ?执行 java类名(字节码文件)

为了使源文件和生成的字节码文件名一致 加修饰符(public) public class Test (不用class Test)

数据类型

基本数据类型

常量池中的值默认空间大小 ??32bit-int?? 64bit-double

1? 3.4 常量值 存储在常量缓冲区中的

常量值的存储形式不是十进制 是以二进制形式存储

?4整型 ?byte(字节型 -128~127) short(2字节) int(4字节) long(8字节)

当数字范围超过int类型的范围时(-2147483648~2147483647)? long后面定义要加L (long a=2147483648L)

?2浮点型 ??float(4字节 32位)?? double(8字节 64位)

float e=3.4; 会出现错误从double转换到float会有损失 ?float e=3.4F(小写大写都可以)

1字符型 char(2字节 16b)为了以示区分 每一个字符前后各加一个单引号

1布尔型boolean(1b) true false 和0 1不同

基本类型与应用类型之间的互相转换(用包装类)

int--Integer ? char--Character ? byte--Byte ?float--Float
int value=Integer.parseInt("123"); ?//将字符串转化为int类型
将基本类型类型转化为引用类型最快的是在后面加一个连接符
5+"" --返回一个"5"的字符串类型 ? ?5+5+"5"+5+5---结果是"10555"

引用数据类型

数组[ ]??? 类class(抽象类abstract class) 接口interface 枚举enum 注解@interface

字符 char 基本 ‘a’ ‘我’ (里面不能大于一个)

字符串(两个及两个以上的字符) String 引用 “a” “abc” “”?? null(什么也没有)

数组[] ?类class 抽象类abstract class 接口interface 枚举enum 注解@interface

基本数据类型和引用数据类型在内存结构上的区别


所有的变量空间都存储在栈内存
变量空间可以存储基本数据类型 ?也可以存储引用数据类型
如果变量空间存储的是基本数据类型 ?存储的是值 ?一个变量的值改变 ?另一个不会跟着改变
如果变量空间存储的是引用数据类型 ?存储的是引用(地址) ?一个变量地址对应的值改变 另一个跟着改变

数据类型之间的转换问题

Int a=1;? int b=a;??? b的值从a空间里面拿出来,而不是从常量缓冲区拿来,a空间的值才是从常量缓冲区拿来

byte a=1;? //8bit

int b=a;? //32bit??? (大的里面可以装小的)

基本类型与基本类型之间可以直接转换(自动 强制)

引用类型与引用类型之间可以直接转换(自动 强制—上转型 下转型)

基本类型与引用类型之间不可以直接转换(间接—包装类/封装类)

小数据类型相同

比较内存空间的大小

都是整型 ?byte a=1; int b=a;//直接转化

int a=1; byte b=(byte)a;//(大空间转小空间不可以直接接受大数据类型的值需要进行强制转化)

都是浮点型

float x=3.4F; double y=x;//自动直接转化

double x=3.4;float y=(float)x;//强制转化

如果发现强制转化之前的数值比较大 强制转化这件事可以执行(可以编译)但是转化后的数值不对(会有损失)

int a=1000; byte b=(byte)a;// 1000转化为二进制后强制转化只保留最后的8bit

小数据类型不同

?比较精确程度 浮点型精确程度更高 可以直接存放整数 反之需要强制类型转换

任何一个浮点型都可以直接存放一个整型

int a=1;? float b=a;//b=1.0

long a=1; float b=a;//b=1.0 自动直接转化

float a=1.0F; int b=(int)a;//强制类型转化

整型字符型之间的转换

每一个字符都有一个对应的Unicode码 ?a---97 汉字也能转换

char x=’a’; int y=x; //y=97 自动转换

int x=97; char y=(char)x;//强制类型转换

布尔类型不能与其他类型发生转换

常量

1.程序在运行过程中 不能再次改变的值

??固定的值 便于程序计算 ex:圆周率3.1415926……

2. 用来代表一个含义

贪吃蛇 1234分别代表上下左右四个方向

String是一个引用数据类型 它的值很特殊 可以简单视为是常量

自己创建一个空间 存储一个值 让他固定起来 不能改变

变量

变量指的是一个内存空间(小容器)

变量空间在创建的时候 必须指定数据类型 变量空间的名字

变量空间 里面只能存储一个内容(值 引用)

变量空间内的内容可以改变

变量如何创建/声明:数据类型 ?变量名字? ?int a;

变量的生命周期(变量在栈内存空间 从声明开始创建出来 用完及回收)

注意: ?

变量是一个空间 可以只创建空间 里面不存放内容。变量空间创建后是没有默认的内容空的。空的变量空间不能拿来使用,如果拿出来使用会出现编译错误。

命名规则

字母(区分大小写) 数字(0~9不允许开头) 符号(英文符号_ $) 中(不推荐)

类名字 首字母大写 如果两个以上的单词 所有首字母大写

变量名 属性/方法/变量 首字母小写 如果两个以上的单词 之后的首字母大写

包 ?全部字母小写(区分关键字)

静态常量 ?全部字母大写(可以利用_分隔)

所有名字都需要见名知义 为了增强程序的可读性

静态常量? 全部字母大写? 用_分隔 ??BOOKSTORE_ADMIN

注释

// 单行注? ? ? ? ? ? ? /*? */ 多行注释? ? ? ? ? ? ? ?/**? */ 文档注释

运算符

用来指明对于操作数的运算方式

按照运算符操作数的数目来进行分类

单目 a++?? 双目 a+b?? 三目 (a>b)?x:y

按照运算符的功能来进行分类

算数运算

[ + -? *? /? %(取余 取模)? ++(自增) --(自减 )]

x++ //(相当于x=x+1)x空间内的值 自增一个 ???++x//对于x空间内的值来讲 都是一致 最终结果增加一个

int x=1;? int y=x++; //x==2? y==1? ++在变量的后面产生一个备份空间,备份空间的值为1,将1赋值给y,原来x的值变成了2

int x=1;? int y=++x; //x==2? y==2 ?++在变量的前面产生一个备份空间,备份空间的值为2,将2赋值给y

x在进行值交换的时候会产生一个副本空间(备份)

++在变量的前面 先自增后备份 ++在变量的后面 先备份后自增 ?会将副本空间的值赋值给别人

Int a=1; a=a++;? //a==1? 产生一个备份空间里面的值为1,a空间此时变成了2,最后在进行赋值运算,把备份空间的值赋值给a

int a=1;
for(int i=1;i<=100;i++){
    a=a++;
}  //a==1
int m=1;//2 1 0
int n=2;//3  2  1
int sum=m++ + ++n-n-- - --m+n-- - --m;  //m==0,n==1,sum==2

赋值运算

?=赋值符号 ????将=右边的内容(值 引用)存入=左边的变量空间

+=? -=?? *=?? /=?? %=?

short m=1; ?m+=2; //m=3? +=是一个赋值符号可以自动转化

m=m+2;//编译出错 类型从int转化为byte可能会有损失 =后面是一 个表达式不可以直接进行转化需要强制转化m=(byte)(m+2)

x空间---8bit 常量区---32bit

+可以自动提升8bit--32bit所以两个不同空间大小的可以加法运算,但是由于m+2是一个表达式=符号不能自动转化表达式

关系运算(比较)

>? >=?? <??? <=?? !=? ==? (对象 ?instanceof 类)

==比较符号 ?比较==前面和==后面的元素(值 引用)是否一致

比较运算符的最终结果是一个Boolean类型(true/false)

注意:==比变量空间里的内容,基本类型的时候是值,比引用类型的是地址 ?“a”.equals(“b”)比较的是引用类型的值是否相同

逻辑运算

逻辑与&(前后两个必须同时满足最终结果才为true)?? 逻辑或| (前后两个只要有一个条件满足最终就为true)? 逻辑异或^(前后两个结果不一致最终结果就是true)?? 逻辑非!(单目运算,将原来的结果取反)

短语与&&? 短路或||

逻辑运算符前后连接的应该是两个boolean类型的结果

(3>2)^(3>5)//true???? (3>2)^(5>3)//false

!(3>2)? //false

(3>4)&&(3>2)? //当前面的值的结果为false 最终肯定为false,短路的是&&之后所有计算结果

如果发生了短路情况,性能比&稍微好一点,短路与不一定提高了性能,只有当前面为false的时候才会发生短路,才会提高性能

逻辑与和短路与从最终的执行结果来看是没有任何区别的

(3>2)&&(3>4) //第一个条件为true,最终肯定为true

位(bit)运算

注意:计算机中不管是正数还是负数 存储的形式都是以补码形式来存储

八制表示形式以0开头 十六进制表示形式以0X开头

按位与&?? 按位或|?? 按位异或^? 按位取反~(单目)?

按位左位移<<?? 按位右位移>>?? 按位右位移(无符号)>>>

?&与&&的区别

&可以视为逻辑运算 可以视为位运算? ? &&只能当作逻辑运算

如果两个符号都当作逻辑运算符来使用时候如下区别:

&前后两个条件都是true 最终结果就是true

&&短路与 正常情况下&执行结果一致

当前条件为false的时候发生短路 最终结果为false

多分支结构

switch(值){//  值可以为(byte  short  int  char)    jdk1.5版本enum   1.7版本String
case 值1:
	代码1;
	//[break;] 可有可无
case 值2:
	代码2;
default:
	代码
}//如果switch里面没有break就会执行全部的条件	

循环

循环想要执行 需要三个必要条件 ?初始值 ?终点判定条件 ?变化量

for( 1初始值 ; 2终点判定条件 ; 4变化量 ){
	3好多好多执行;
}

允许将三个条件都写在()内 ?不是必须

初始值 ;
for( ; 终点判定条件 ; ){
	好多好多执行;
	变化量 ;
}

break continue ? 循环标记,用来选择终止哪一个循环体

int i=1;
int j=1;
ok:for(;i<=5;i++){
	ko:for(;j<=5;j++){
			if(j==3){
				break ok;
			}
			System.out.println("哈哈哈");
		}
}

数组

数组的定义(声明)
int[] x; ? int x[] ? int []x;三种都可以,一般是第一种形式
静态初始化:有元素有长度
?? ?int[] array={10,20,30,40};
?? ?int[] array; ? ?array=new int[]{10,20,30,40};
?? ?int[] array = new int[]{10,20,30};
动态初始化:有长度没有元素(不是真的没有 默认值)
?? ??? ??? ?int[] array = new int[5];
?? ??? ??? ?整数默认值---0
?? ??? ??? ?浮点数默认值---0.0
?? ??? ??? ?字符型默认值--- ?0---char(默认值看不见的) ?0数字对应的code码(不是空格) ? ? 97-a ?65-A ?48-'0'
?? ??? ??? ?布尔型默认值--- ?false
?? ??? ??? ?引用数据默认值--- null?? ?String[]
取数组中的元素 int value=array[3];(取出数组中的第四个元素)
修改数组中的元素 array[3]=400;
数组的索引从0开始到数组长度-1
数组的遍历
for(int value:array){
? ?System.out.println(value);
?? ?}
char类型的数组可以使用输出语句直接打印输出数组里的元素

array=null;数组不用了,被当作垃圾回收了

int[] x = new int[]{10,20,30};
int[] y = x;
y[0] = 100;
System.out.println(x[0]);//?   100

二维数组内存结构:

int[][] array = new int[3][2];
array[0][0] = 10;
array[0][1] = 20;
array[1] = array[0];
array[0] = new int[4];
array[0][0] = 100;
System.out.println(array[1][0]);//?   10

形参和实参

形参可以理解为是方法执行时的临时变量空间 ?x
实参可以理解为是方法调用时传递进去的参数 ?a
方法调用时会将实参的内容传递给形参
如果内容是基本类型 ?传递的 是值 ? ?形参改变 ?实参不变
如果内容是引用类型 ?传递的 是引用 ?形参改变 ?实参跟着改变

?类

类-----抽象 笼统的概念
? ?属性
?? ??? ?权限修饰符 [特征修饰符] 属性类型 属性名字 [= 值]; ?(如果不写是有默认值)
?? ??? ?属性不存在重写?
? ?方法
?? ??? ?权限修饰符 [特征修饰符] 返回值类型 方法名字 ([参数列表]) [抛出异常] [{方法体}]
?? ??? ?方法重载overload
?? ??? ?一个类中 一组方法 ?名字相同 ?参数列表不同 ?构成方法重载
?? ??? ?参数不同体现在 ?个数 类型 顺序
?? ??? ?动态参数列表使用?
?? ?注意:如果方法中没有写返回值类型,在方法中写一个return相当于结束这个方法

public void add(){
       if (3>2) {
           System.oue.println(true):
      } else {
           return;
       }
}

构造方法

权限修饰符 与类名一致的方法名 ([参数列表]) [抛出异常] {方法体}
1.作用 : 用来创建当前类的对象
2.结构和写法 : 没有返回类型 ?有返回值
3.调用 : 通过new关键字
4.特点 : 每一个类都有默认无参数的构造方法 我们自己定义了新的 ?默认的构造方法即被覆盖
? ? ? ? ? ? ?构造方法也存在方法重载
不用特征修饰符修饰构造方法

程序块(代码块)

可以理解为是一个非常特殊的方法
没有修饰符 没有返回类型 没有名字 没有参数
只有一个方法的执行体{}
程序块是在每一次调用构造方法之前都会默认自动执行
程序块没有重载 ?却可以存在多个 ?按照创建的顺序逐一执行
特征修饰符只有static

this关键字的使用

1.指代词 ?代替的是调用属性/方法时的当前的对象
2.this既然是一个对象 ?可以调用一般属性 可以调用一般的方法
? ? ? ? 放置在类成员的任何位置(四个成员都可以)
? ? ? ? 方法之间来回的调用???
? ? ? ? 写法可以的(编译好用) ?执行可能会产生StackOverflowError 栈溢出错误
3.this也可以调用构造方法 ?this(); //省略了构造方法的名字,因为构造方法的名字和类名一样
? ? ? ? ?将这给代码放在另一个构造方法内 ?需要在第一行

super关键字的使用

  1. 调用父类构造方法
    在子类的构造方法中,可以使用?super?关键字调用父类的构造方法。这是子类构造方法中的第一个语句,并且必须存在。

class Parent {  
    Parent() {  
        System.out.println("Parent Constructor");  
    }  
}  
  
class Child extends Parent {  
    Child() {  
        super(); // 调用父类的构造方法  
        System.out.println("Child Constructor");  
    }  
}

2. 访问父类的受保护或包级私有属性
如果子类需要访问父类的受保护或包级私有属性,可以使用?super?关键字。

class Parent {  
    protected String name = "Parent Name";  
}  
  
class Child extends Parent {  
    public void printName() {  
        System.out.println(super.name); // 访问父类的受保护属性  
    }  
}

3. 调用父类的方法
如果子类需要调用父类的方法,可以使用?super?关键字。这可以在子类方法内部进行,或者在重写的方法内部进行。

class Parent {  
    public void display() {  
        System.out.println("Parent display");  
    }  
}  
  
class Child extends Parent {  
    public void display() {  
        super.display(); // 调用父类的方法  
        System.out.println("Child display");  
    }  
}

4. 访问父类的静态变量和方法
使用?super?关键字可以访问父类的静态变量和方法。这在子类中访问父类的静态成员时很有用。

区别:

?? ?this和super都是指代词 ?代替的是对象
?? ?this代替的是当前执行方法时的那个对象 ?不一定是当前类的(当父类和子类里面有一样的方法(一般方法)时,在父类里面
? ? ? ? ? ?调用这个方法时,执行的是子类的方法,不是父类的) ? ? ?在父类里面调用其他重载的构造方法时,还是使用this调用
?? ?super代替的是当前执行方法时的对象的父类对象 ?空间内部的那个
?? ?都能调用一般属性 和 一般方法
?? ?可以放置在类成员的任意位置(属性 方法 构造 块)
? ? ? ? ? 注意调用一般方法的时候可以来回互相调用(写法 编译好用) 执行可能产生问题(StackOverflowError)
?? ?可以调用构造方法(放在构造方法的第一行)
? ? ? ? ? this和super在构造方法中调用另一个类的构造方法不能同时出现在第一行(super会默认出现在子类构造方法的每一行
? ? ? ? ?随便调用一个子类的构造方法时,都会有一个父类的构造方法被先调用出来)
?? ?如果第一行调用其他的构造方法时,就会被占用)
? ? ? ? ? 构造方法之间不能来回互相调用(编译就不好用) ?
? ? ? ? ? 当子类调用构造方法时,会默认先调用父类的构造方法

方法重载??

1. 概念:一个类中的一组方法 ?相同的方法名字 ?不同的参数列表 ? 这样的一组方法构成了方法重载
? ??? ??? ?参数列表的不同体现在哪里?
? ??? ??? ?参数的个数 ? 参数的类型 ? 参数的顺序
2. 作用:为了让使用者便于记忆与调用 ? 只需要记录一个名字 ?执行不同的操作 ?
3. 自己也可以设计方法重载
? ??? ??? ?调用方法的时候 ?首先通过方法名字定位方法
? ??? ??? ?如果方法名字有一致 ?可以通过参数的数据类型定位方法
? ??? ??? ?如果没有与传递参数类型一致的方法 ?可以找一个参数类型可以进行转化(自动)
4. JDK1.5版本之后 出现了一个新的写法
? ??? ??? ?int... x?? ?动态参数列表?? ?类型固定?? ?个数可以动态 0--n都可以
? ??? ??? ?x本质上就是一个数组 ?有length属性 ?有[index]
? ??? ??? ?动态参数列表的方法 ? 不能 ?与相同意义的数组类型的方法构成方法重载 ?本质是一样的
? ??? ??? ?动态参数列表的方法 可以不传参数 相当于0个 数组的方法 必须传递参数
? ??? ??? ?动态参数列表在方法的参数中只能存在一份儿 ?且必须放置在方法参数的末尾

方法重写

  1. 方法名称、参数列表和返回类型必须与父类方法相同。
  2. 子类方法的访问修饰符不能比父类方法的访问修饰符更严格。例如,如果父类方法是public的,则子类方法可以是public或protected,但不能是private。
  3. 子类方法不能抛出比父类方法更广泛的异常。
  4. 子类方法的返回类型必须是父类方法返回类型的子类型。
  5. 子类方法不能使用比父类方法更严格的访问修饰符,例如,如果父类方法是public的,则子类方法可以是public或protected,但不能是private。

类和类的关系

is-a?? ??? ?继承 ? 实现
?? ??? ?继承通过extends关键字 (单继承)
?? ??? ?实现通过implements关键字 (多实现 接口)
?? ??? ?注意方法重写 ?方法重载区别 ? ?注意Object类及方法 ? 注意内存结构
has-a?? ??? ?组合 ? 聚合 ? 关联 ?(一来就有)
?? ??? ?一个类的对象放置在另一个类中作为属性
use-a(need-a)?? ?依赖 ?(后天组合在一起)
?? ??? ?一个类的方法中使用到了另外一个类的对象 ? ?方法内部new ?方法传递参数
类关系的设计: 高内聚 低耦合 ? ? ?继承(实现) > 组合 > 聚合 > 关联 > 依赖

权限修饰符

public公共的本类同包子类当前项目中任意类的位置只要有对象都可以访问
protected保护的本类同包子类通过子类对象调用父类里面的protected方法,在子类范围内 子类对象可以自己访问,不在同一包中时调用父类自己的protected调用不到
默认不写默认的本类同包
private私有的本类

特征修饰符

final

最终的 不可更改的

  1. 修饰变量 如果在定义变量时没有赋初始值 给变量一次存值的机会(因为变量在栈内存空间内 没有默认值 如果不给机会 就没法用啦) 一旦变量被存储了一个值 若用final修饰后 则不让再次改变 ----> 相当于常量啦(值没法动) 注意 变量类型是基本类型还是引用类型 如果修饰的变量是基本数据类型 则变量内的值不让更改---常量 如果修饰的变量是引用数据类型 则变量内的地址引用不让更改---对象唯一
  2. 修饰属性 全局变量 存储在堆内存的对象空间内一个空间 属性如果没有赋值 有默认值存在的 属性用final修饰后 必须给属性赋初值 否则编译报错 特点与修饰变量一致 注意 变量类型是基本类型还是引用类型 如果修饰的变量是基本数据类型 则变量内的值不让更改---常量 如果修饰的变量是引用数据类型 则变量内的地址引用不让更改---对象唯一
  3. 修饰方法 方法是最终的方法 不可更改 子类继承父类的方法 将父类的方法重写(覆盖) final修饰的方法 要求不可以被子类重写(覆盖)
  4. 修饰类本身 类是最终的 不可以更改 (太监类 无后) 此类不可以被其他子类继承 通常都是一些定义好的工具类 Math Scanner Integer String

static

修饰属性 ?修饰一般方法 ?*修饰块 ?修饰类(内部类)

特点:

  • 静态元素在类加载时就初始化啦,创建的非常早,此时没有创建对象

  • 静态元素存储在静态元素区中,每一个类有一个自己的区域,与别的类不冲突

  • 静态元素只加载一次(只有一份),全部类对象及类本身共享

  • 由于静态元素区加载的时候,有可能没有创建对象,可以通过类名字.的形式直接访问

  • 可以理解为静态元素不属于任何一个对象,属于类的

  • 静态元素区Garbage Collection(垃圾回收器)无法管理,可以粗暴的认为常驻内存

  • 非静态成员(堆内存对象里)中可以访问静态成员(静态区)

  • 静态成员中可以访问静态成员(都存在静态区)

  • 静态成员中不可以访问非静态成员(个数 一个出发访问一堆相同名字的东西 说不清)(静态元素属 于类,在静态元素区 非静态成员属于对象自己)

  • 静态元素中不可以出现this或super关键字(静态元素属于类)

静态常量 全部字母大写 用_分隔 BOOKSTORE_ADMIN

静态常量的应用场景

增强程序的可读性 static final 属性=0

abstract

抽象的---(很不具体 没有具体的执行 只是个概念,没有执行体)

??? ?1. 可以修饰什么
? ? ? ? ? ? ? ? ? ? 不能修饰属性 属性是一个变量空间(容器) 抽象不了
? ? ??? ?修饰方法?? ?用abstract修饰符修饰的方法 ?只有方法的结构 没有方法执行体叫做抽象方法
? ? ??? ?当然注意native修饰的方法虽然也没有方法体 但是不是抽象方法 只是执行的过程是其他语言写的 看不见
? ? ??? ?修饰类
? ? ??? ?用abstract修饰符修饰的类 叫做抽象类
??? ?2. 修饰后有什么特点
? ? ??? ??? ?抽象类中必须有抽象方法么? ?不是必须含有抽象方法 ?
? ? ??? ??? ?抽象方法必须放在抽象类中么? ?目前来看必须放在抽象类中(或接口中) ?普通类是不允许含有抽象方法
??? ?3. 研究一下什么叫抽象类 ?抽象类有什么特点?(通常用来描述事物 还不是很具体)
? ? ??? ?1. 类里面有什么 ?成员
? ? ? ? ??? ??? ?属性?? ?可以含有一般的属性 ?也可以含有 private static final等等(跟普通类的属性一样)
? ? ? ? ??? ??? ?方法?? ?可以含有一般的方法 ?也可以含有 private static final等等(跟普通类里面的方法使用一样)
? ? ? ? ??? ??? ??? ? ? 注意:抽象类中是允许含有抽象方法(只有方法结构 没有方法执行体)
? ? ? ? ??? ??? ?块?? ?可以含有一般的程序块 也可以含有static程序块
? ? ? ? ??? ??? ?构造方法?? ?可以含有构造方法 ?包括重载 ?抽象类不能通过构造方法创建对象
? ? ??? ?2. 类如何使用 ?创建对象
? ? ? ? ??? ??? ??? ?抽象类含有构造方法 ?但是我们不能通过调用构造方法直接创建对象
? ? ? ? ??? ??? ??? ?抽象类只能通过子类单继承来做事
? ? ? ? ??? ??? ??? ?为什么不让我们调用构造方法创建对象?因为抽象方法是一种概念(残次品)
? ? ? ? ??? ??? ??? ?为什么还有呢?必须通过子类继承来实现,子类会间接调用父类的构造方法如果没有就调用不到
? ? ??? ?3. 类和类的关系
? ? ? ? ??? ??? ??? ?抽象类----直接单继承----抽象类?? ? 可以
? ? ? ? ??? ??? ??? ?抽象类----直接单继承----具体类 ?可以 ?(用法通常不会出现)
? ? ? ? ??? ??? ??? ?具体类----直接单继承----抽象类 ?不可以 ?(将父类的抽象方法具体化 ?或子类也变成抽象类)
? ? ??? ?4. 小问题
? ? ? ? ??? ??? ?抽象类中能不能没有抽象方法 ?全部都是具体成员 ?可以
? ? ? ? ??? ??? ?抽象类中能不能没有具体成员 ?全部都是抽象方法 ?可以 ---> 抽象类抽象到极致 质的变化 ---> 接口
? ? ? ? ??? ??? ?接口可以理解为是抽象类抽象到极致--->还是一个类的结构 ? 不能用class修饰 改用interface修饰

接口

什么是接口(通常是为了定义规则) ?如果一个类实现了接口就必须把接口里面的方法具体化

接口也是一个类的结构 ?只不过 用interface修饰 替换原有的class

只定义规则 ?不描述具体过程

  1. 有什么成员 属性 不能含有一般属性 只能含有公有的静态的常量 public static final (这三个修饰符都是可以默认不写的,写与不写都是代表这三个) 方法 不能含有一般方法 只能含有公有的抽象的方法(1.8 defualt修饰具体方法) 块 不能含有一般程序块 也不能含有static块(块本身就是具体的 接口中不让有具体的) 构造方法 不能含有构造方法 接口没有构造方法,不能创建对象,只能通过子类多实现(implements)来做事

  2. 如何使用 创建对象 不能创建对象 只能通过子类多实现(implements)来做事 public class A implements B,C,D{ }

  3. 与别的类结构关系 接口不能继承别的类 最抽象 抽象类----直接多实现----接口 可以 具体类----直接多实现----接口 不可以(必须将接口中抽象的方法具体化(重写)或自己变成抽象类) *接口---多继承---接口 可以直接多实现

?? ?接口通常定义规则 ? ? 抽象类用来描述事物 ? ? 类用来具体描述细节

类的加载顺序

1. 加载父类

2. 父类会产生自己的静态空间 ? 属性 方法 块
? ? ? ? ? ? ? ? ?执行静态块

3. ?加载子类

4. 子类会产生自己的静态空间 ? 属性 方法 块
? ? ? ? ?执行静态块

5. ?开辟对象空间

6. 加载父类的非静态成员 ? 属性 方法 块 构造方法

7. 执行块 ?执行父类构造方法

? ?加载子类的非静态成员 ? 属性 方法 块 构造方法

8. 执行块 ?执行子类构造方法

9. 将对象空间的地址引用交给 变量来存储

创建对象在堆内存

方法在栈内存临时执行,用完即被回收

在创建对象前会先在方法区加载一个类模板

引用数据类型赋值时是看堆内存中的地址

堆内存中的元素在没有指定时都是有默认元素的

new一个东西就会在堆内存开辟一个空间

执行main时会在栈内存开辟一个空间

执行main里面调用方法? 又会在栈内存开辟一个空间执行

多态

同一个对象体现出来的多种不同形态(身份) 将一种行为表现出不同的效果要想实现多态的效果 需要现有继承关系 使用多态的前提是需要有继承关系。

体现:

1. 父类类型的引用 ?指向 ?子类的对象 ? ?
? ?Person p = new Teacher();//做了一个自动的向上转型
? 调用的属性执行的时Person(父类)中的属性?
? ?当调用的一个方法如果Teacher里面有这个方法时就执行Teacher里面的方法 ? 如果Teacher里面
? ? ? 没有这个方法就从Teacher一层一层往上找,最先在哪里找到就执行哪里的 ?可以执行Person独有的方法
2. .该引用只能调用父类中定义的属性或方法?? ?
3. 如果子类中将父类的方法重写,那么调取方法后执行的结果是子类重写之后的那个结果
? ??? ??? ??? ?如果父类与子类有同名的属性 ??? ??? ?执行父类的属性(属性没有重写这一说法)
? ??? ??? ??? ?如果父类与子类有同名的方法(重载)?? ?执行子类重写之后的方法
4. 若想要调用子类中独有的成员
? ??? ??? ??? ?(强制类型转化) ?造型 铸型 ?(向上/向下转型)
? ? ? ? ? ? ? ?Teacher t=(Teacher)p;//向下转型需要强制转换
? ? ? ? ? ? ? ?调用属性时执行的是Teacher的属性 如果调用的方法如果没有在Teacher中就看继承关系
5. 造型时(强制向下转型时) 若需要转换的类型与真实对象的类型不匹配 会产生一个
? ??? ??? ?运行时异常ClassCastException
? ??? ??? ??? ?ClassCastException ? 造型 ?铸型 异常
? ??? ??? ??? ?如果想要避免造型的异常 ?可以用instanceof关键字来进行判断
? ??? ??? ??? ?对象 ?instanceof ?类 ?(p instanceof Teacher)比较前面对象和后面类型是否匹配

内部类

指的是在Java中可以将一个类定义在另一个类的内部。内部类可以定义在 类的内部 (与类成员层次

一致) 内部类可以定义在 方法/块内部 (与类成员相差一个层次 方法的局部变量一个层次)。

  1. 成员内部类 将一个类直接定义在类的里面,作为成员,与属性或方法层次一致
    成员内部类可以与正常类一样 使用不同的修饰符来修饰
    好处1.省略了一个.java文件 好处2.成员内部类中可以访问外部类的所有成员 包括私有的
    若想要在内部类中通过对象.调用外部类成员 外部类.this.外部类成员;
    内部类存在后 源代码进行编译 产生一个字节码 Demo$InnerDemo.class 如果想要使用内部类的属性和方法 必须创建对象 通过外部类对象操作

    Demo d=new Demo(); 
    Demo.InnerDemo id=d.new InnerDemo();
  2. 局部内部类 将一个类定义在方法/块里面,作为成员的内部结构,与临时的局部变量一个层次 局部内部类像是一个局部的变量一样,不能用public protected private及static
    只能用abstract或final
    局部内部类命名规则Demo$1InnerTestMethod Demo$2InnerTestMethod
    局部内部类使用的变量只能是final修饰
    局部内部类可以访问外部类成员 局部内部类也能访问局部变量要求局部的变量必须是final

  3. 匿名内部类 成员匿名内部类 局部匿名内部类?
    通常接口或抽象类的具体子类这样写,当然具体的类也可以有匿名子类
    开发中为了省略一个类文件 上述写法比较常见
    匿名内部类很特殊 只有类体 没有类的所有结构( 修饰符 名字 继承 实现)
    不能用任何修饰符来修饰 匿名内部类也没有构造方法

    public interfase Test{
    		public void test();
    	}
    	public class TestMain{
    		public static void main(String[] args){
    			Test t = new Test(){
    				public void test(){
    				}
    			};
    		}
    }
  4. 静态内部类 成员静态内部类 不需要外部类对象,通过正常的方式直接创建内部类 静态元素不能访问非静态成员(自己类和外部类)

异常Exception

运行时异常(非检查异常)

InputMisMatchException 输入类型不匹配

input.nextInt();? 输入一个整数a

ArrayIndexOutOfBoundsException 数组索引越界

静态初始化? int[] array = {10,20};

array[2]? 索引超出边界

NegativeArraySizeException 创建数组时候长度给了负数 数组的长度不合法

?动态初始化? int[] array = new int[-2];

NullPointerException

?引用为null可以?? 还拿来使用就不行啦

int[][] array = new int[3][];

array[0][0] = 10; //空元素再拿来用

int[] array = null;

array[0] = 10;//空元素再拿来用

Person p=null;//可以为空

p.toString();//为空还拿来用就会出现异常

NumberFormatException

数字格式化异常—将字符串转化为数字发现字符串里面不是数字

Integer.parseInt(“a”)

ArithmeticException

数学异常 ??整数/0??

(小数可以除0)//除以0结果为infinity(无穷)

ClassCastException??

造型? 铸型 异常

造型时(强制向下转型时) 可能会出现一个运行时异常

将对象类型还原时 与真实类型不匹配

illegalArgumentException??? 非法参数异常

ArrayList? list = new ArrayList(-1);//长度给负数

Random r = new Random();

r.nextInt(int bound);?? 随机产生一个? [0--bound)? 整数?

注意bound必须为正数? 否则会出现异常

StringIndexOutOfBoundsException 字符串越界

String str = "abc";

str.charAt(5);

IndexOutOfBoundsException 集合越界

List家族

ArrayList? list = new ArrayList();

list.add(); list.add(); list.add();

list.get(5);

错误error

StackOverflowError 栈溢出错误 ??方法来回调用

原因:构造方法之间来回的调用(每次调用都会产生一个新空间,原来的空间还没有执行完毕)

OutOfMemoryError

堆内存溢出错误

文章来源:https://blog.csdn.net/weixin_47110096/article/details/135477916
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。