JavaSE基础(W3)总结
Day1
1.对象创建完成后内存发生的事情
现有一个Student测试类
Student s = new Student();
1)加载Student.class这个类
2)为s在栈内存中开辟空间
3)在堆内存中申请空间
4)给Student类的属性系统默认初始化通过执行Student类的无参构造方法
5)产生一个堆内存地址空间
6)将堆内存地址值赋值给栈内存变量s
7)栈内存变量s指向堆内存" new Student() "地址值
2. Satatic关键字
Java提供了一个关键字:static :可以被多个对象"共享,共用"
static关键字的特点:
1)static 随着类的加载而加载 (static相关的都先进内存! )
2)优先于对象存在
类的加载:类名.class (优先的)
对象的创建:类名 对象名 =new 类名() ;
Test t = new Test();
3)不能和this共用!
4)被静态修饰的变量/方法称为 "静态变量","静态方法" 有共享,共用的意思
5)被静态修饰的变量或者方法,推荐使用的类名访问
类名.静态变量名;
类名.静态方法名() ;
不推荐使用:类名 对象名 = new 类名() ;
对象名.静态变量名;
对象名.静态方法名() ;
static静态的使用注意事项:
1)非静态的成员方法:
可以访问静态的成员变量,也可以访问非静态的变量!
包括静态方法或者非静态方法
2)静态的方法
静态只能访问静态! (这些静态变量/方法都是跟类相关的!)
3.文档说明书
产生文档说明书:针对ArrayTool.java文件产生API 文档解析
进入到本地目录下:
使用javadoc -d doc(目录名字) -author -version ArrayTool.java(针对哪个Java文件产生文档解析)
/**
这是针对数组操作的自定义工具类//添加注释
@author 作者
@version 版本
*/
4.代码块
什么是代码块:在Java中,使用{}包裹起来的代码,都称为"代码块"
代码块的分类:局部代码块、静态代码块、构造代码块
局部代码块:
在局部位置(方法定义中){xx},作用, 限定局部变量的生命周期,不能超过这个范围访问
构造代码块:
在类的成员位置中使用{}包裹起来的代码,
作用将多个构造方法中相同的代码存储在构造代码块中,在执行构造方法之前先执行,对数据进行初始化!
特点:每次执行构造方法之前,如果存在构造代码块,优先执行构造代码块,在执行构造方法!
静态代码块:
在类的成员位置:
static{
...
}
静态随着类的加载而加载,类加载一次,静态代码块就执行一次
静态代码块优先执行!
构造代码块,构造方法,静态代码块的优先级
静态代码块 > 构造代码块 > 构造方法 !
5.成员变量定义时机
1)方式一
//推荐
class Demo{
//成员方法
public int sum(int a,int b){
return a + b ;
}
}
class VariableDemo{
public static void main(String[] args){
//测试
//创建Demo类的对象来访问sum方法
Demo demo = new Demo() ;
int result = demo.sum(10,20) ;
System.out.println("result:"+result) ;
2)方式二
//将a,b这两个变量:放在类中,作为成员变量
class Demo{
int a ;
int b ;
//求和
public int sum(){
return a + b ;
}
}
Demo d = new Demo() ;
d.a = 10 ;
d.b = 40 ;
int result = d.sum() ;
System.out.println("result:"+result) ;
判断两种方式的优劣
方式1和方式2都可以完成需求:
方式2弊端:将a,b定义为成员变量, 什么时候将变量定义成员变量
如果当前这个变量能够描述真实事物的属性,这个时候将变量定义成员变量
而如果不能够体现出现真实事物的属性,将变量定义局部变量;
没有明确要求的情况下,都优先定义为局部变量,局部变量随着方法调用而存在,随着方法调用结束而消失!
6.继承
什么是继承:将多个类的共性内容抽取在一个独立的类中,然后独立的类和这些类产生一种"继承"关系
Java提供的"继承" 特征 的好处:
1)提高了代码的复用性
2)提高了的代码的维护性
3)让类与类之间产生关系 是 "多态的前提条件"
继承的格式:
class 父类名{}
class 子类名 extends 父类名{}
class Person{//父类
private String name ;//定义成员变量
prvate int age ;
public Person(){}
//有参构造方法
//setXXX()/getXXX()
}
class Student extends Person{}//直接调用父类中的成员变量
class Teacher extends Person{}//直接调用父类中的成员变量
注意事项:子类继承父类,只能继承父类非私有的成员,私有的成员,外界不能访问的,只能间接通过
公共方法访问!
子类中的功能:一般都是一些子类的特有功能
开发中,设计原则: 都要遵循 :"低耦合,高内聚"
耦合:类与类的产生的关系
低耦合:这种关系越少越好! "耦合"----只能避免,不能彻底解决!(Spring框架:IOC 控制反转)
内聚:执行某件事情的能力
高内聚:在一个类中能够完成的事情,不要使用多个类完成事情!
Day2
继承的特点
继承的特点:将多个类的共性内容抽取到一个独立的类中,让这独立类和这些类产生一种关系 "继承"
继承的好处:
1)提高了代码的复用性
2)提高了代码维护性
3)类与类之间关系 ,是"多态"的前提条件
1)在Java中,类与类之间的继承关系,只支持单继承,不支持多继承!
2)在Java中,类与类之间虽然不能 多继承,但是可以 多层继承!
继承中,一个类的组成
1)成员变量
2)构造方法
3)成员方法
什么时候使用继承
什么时候使用继承
继承的中的另一个注意事项
不要为了使用部分功能,而使用继承!
如果A类是B类的一种,或者B类是A类的一种,这个时候使用继承!
继承的体现出的是一种"is a"的关系:xxx 是xxx的一种.
举例:"苹果,香蕉,橘子是水果的一种"
继承中成员变量访问问题
在继承中,成员变量访问问题!
1)子类继承父类,如果子类的成员变量名称和父类的成员变量名称不一致的情况:
比较简单,分别访问即可
2)子类继承父类,如果子类的成员变量名称和父类的成员变量名称一致的情况:
a)先在本类的局部位置找,有没有这个变量,如果有就直接使用
b)如果本类的局部位置没有,在本类的成员位置中找,如果有,就使用
c)如果本类的成员位置没有,在它的父类的成员位置找,如果有,就使用
d)父类的成员位置都没有这个变量,压根不存在,就报错!
遵循一个原则:"就近原则"
继承中构造方法的访问
继承关系中,构造方法的访问
子类继承父类,不能够继承构造方法,但是可以通过super()间接访问父类的构造方法,让父类先进行初始化
子类的所有构造方法都默认访问父类的无参构造方法:子类的每一个构造方法的第一句话:super();
super:代表的是否父类的空间标识(代表父类的对象的地址值引用)
为什么要去让父类初始化呢?
因为子类继承父类,
可能会使用到父类的数据!所有必须先让父类初始化,然后子类在初始化(分层初始化)
在写父类的时候:在继承中由于存在默认的访问问题,建议永远给出父类的无参构造方法
继承关系中,成员变量访问问题 :如果子类继承父类,成员变量名称都一致, 就近原则
需要现在子类的局部位置找,有就使用
没有,在子类的成员位置找,有就使用
没有,在父类的成员位置找,有就使用
2.this和super的区别
this和super的区别
this:代表的本类对象的地址值引用
super:代表的父类空间标识(父类对象的地址值引用)
this.变量:访问的本类的成员变量
this.方法名():访问的本类的成员方法
this()/this(xx):访问本类的无参构造方法/访问的本类的有参构造方法
super.变量名:访问的是父类的成员变量
super.方法名():访问的父类的成员方法
super()/super(xx):访问的父类的无参构造方法/访问的父类的有参构造方法
3.idea快捷按钮
该类名/包名-----shift+f6:更改
单行注释---- ctrl+/ (再次ctrl+/:取消单行注释)
多行注释----ctrl+shift+/:加入多行注释 (再次:ctrl+shift+/:取消多行注释)
复制行: ctrl+d
删除行: ctrl+x
需要在当前类在红导入别的类:选择这个类: alt+enter--->回车 导入即可!
自动补全代码:
1)new 类名().var---->代码自动补全
2)new 类名(); alt+enther--->回车 即可
4.方法重写override
方法重写:override:
子类继承父类,出现了和父类一模一样的方法声明(权限,返回值,方法名,参数列表都相同),方法覆盖
为了将父类的功能覆盖掉,使用自己的功能!
子类和父类出现一模一样的方法:方法名相同,返回值相同,权限修饰符都一样
@Override :jdk提供的内置注解 ,可以不写
5.final关键字
子类继承的父类的时候,有时候需要将父类的功能覆盖掉,完成的自己的功能!
但是,有的时候不能覆盖
举例:
有一个父类,父类中有一个方法,show().
定义一个子类,子类将父类的show()覆盖掉,直接将父类的功能覆盖了
现在就不想让父类的功能被覆盖掉,Java提供了一个关键字:final: 状态修饰符 (最终的,无法更改的)
可以修饰类,可以修饰变量,可以修饰方法
final:最终的,无法更改的
可以修饰类,该类不能被继承
,可以修饰变量,此时这个变量是一个常量:自定义常量
此时这个变量只能被赋值一次,再次赋值,报错!
可以修饰方法,
此时这个方法不能被重写!
成员变量被final时:必须先初始化
public final int num = 100 ;
final关键字修饰基本类型/引用类型的区别
final关键字修饰基本类型/引用类型的区别
final:本身:最终的,无法更改的 状态修饰符
当final修饰基本数据类型,基本数据类型的值不能再改变,只能赋值一次!
开发中,定义基本数据类型的常量:
在一个类的成员位置:
public static final int xxx = xx ;
当final修饰引用数据类型,引用数据类型的地址值不能在改变!
在开发中, 在一个类中引用类一个类的实例!
Day3
1.什么是抽象类
什么是抽象类?
在现实世界存在真实事物,本身就是概括性的事物,这个时候,为了将具体的事物的功能给出具体体现,那么当前概括性的事物中
加入抽象-----abstract,并且它里面的一些功能仅仅只是声明,并不给出具体体现!
举例:
猫狗案例---->抽取动物类 :父类 (概括性的)
吃/睡的功能 ---- 只有具体的猫和狗,才有具体的吃的,睡的功能!
java提供了关键字----> 在类上加入一个修饰: abstract
abstract class 抽象类名{
}
如果一个类中有抽象方法,那么这个类一定是抽象类;
如果一个类是抽象类,不一定有抽象方法!
什么时抽象方法
什么叫抽象方法?
抽象方法就是没有方法体的方法;
public abstract 返回值类型 方法名(形式参数);
例:public abstract void sleep() ;
抽象类有一个特点:
抽象类不能实例化-----不能 new
抽象类的子类:
1)是抽象类,也不能实例化!
如果仅仅存在父类,和子类,这个子类还是抽象类---毫无意义! new 不了!
2)研究的具体类: 可以实例化的!
对象的创建还是子类创建的!
抽象的父类名 对象名 = new 子类名() ; //抽象类多态
例: Animal a = new Cat()
抽象类的本质---->就是强制子类必须要将父类的中抽象功能,重写!
多态
多态:
一个事物在不同时刻体现的不同形态(内存中的变化)
要使用多态,要遵循它的前提条件:
1)必须存在继承关系 (没有继承关系,没有多态!)
2)必须有方法重写 (子类继承父类,需要将父类的功能覆盖掉)
使用子类的功能;
3)必须存在父类引用指向子类对象("向上转型")
class Fu{}
class Zi extends Fu{}
之前:Zi zi = new Zi() ;
现在:多态: Fu f = new Zi() ;
在多态中,的成员访问特点:
Fu f = new Zi() ;
非静态
成员变量:编译看左,运行看左
成员方法:编译看左,运行看右 :由于存在子类重写父类的功能,所以使用的子类的功能
静态方法: 静态的东西都是跟当前类有关系:优先进内存(随着类的加载而加载)
静态方法--算不上方法重写:编译看左,运行看左
构造方法:父类先初始化,然后子类在进行初始化
多态的好处及弊端
多态的好处是什么?
1)可以提高代码的复用性 (是由继承保证的)
2)可以提高代码的扩展性(多态完成:父类引用指向子类对象:Fu f = new Zi()) ;
多态的弊端:
不能访问子类的特有功能!
向上转型:父类引用指向子类对象
如果能够使用子类型,就可以访问它的功能!
解决方案:
1)子类 引用 指向自己本身:子类对象
虽然可以访问,但是多态中,不推荐,因为重新new 对象,消耗堆内存空间
2) 将父类引用强制转换为子类引用 :向下转型 ,前提:必须存在向上转型
Fu f = new Zi() ;//向上转型
Zi z = (Zi)f ; //向下转型
推荐2) :不会重新在堆内存中开辟空间,结束内存空间!
多态的向下转型,如果使用不当,会出现异常!
ClassCastException:类转换异常: 堆内存中的变化 和接收的类型不匹配!
Day4
方法重写的注意事项:
方法重写的注意事项:
子类继承父类,要重写父类的功能的时候,必须要保证子类的方法的访问权限足够大,要么
就父类的权限保持一致即可!
抽象类关键字与权限修饰符冲突问题
抽象 的关键字:
abstract不能和哪些关键字使用(冲突)
abstract可以修饰类,这个类不能实例化了,这个类叫抽象类
abstract可以修饰方法----抽象方法:没有方法体
和private关键字不能一块使用:被private修饰的只能在本类中访问,外界类中的成员不能访问!
和static关键字冲突:如果加了静态,子类要重写父类的方法,这种访问方式: 多态:Fu f = new Zi() ;f.方法名() ;
静态的方式--->随着类的加载而加载: 类名.方法名();
和final关键字冲突:被final修饰的方法不能被重写,而abstract抽象方法,要强制子类必须重写,否则子类报错,出现冲突了!
abstract:和默认修饰符 abstract 返回值类型 方法名(形参列表) ;
和public可以使用
和protected:
限定的是子类: 在同一个包下/或者在不同包下 都可以访问
什么是接口
什么是接口?
接口是比抽象类还抽象的事物,它体现的一种 "扩展性"--- 事物的额外功能!
如果一些具体事物能够将额外功能实现了,那么这些具体事物就应该具备这些功能了!
接口:体现的是一种 "like a"的关系
定义格式:
interface 接口名{ //接口名要见名知意---符号"标识符的规则"
}
接口中的方法:只能是抽象方法
接口特点:不能实例化:不能new
将接口的子类称为"子实现类"
可以是抽象类, 一定会有抽象类的具体的子类,否则没有意义!
也可以是具体类 : 通过具体类实例化
接口名 对象名 = new 子实现类名() ;
子实现类和接口之间的关系:实现关系 :implements
class 子实现类名 implements 接口名{
}
接口成员的特点
接口的成员特点
成员变量:只能是常量:存在默认修饰符:public static final ... :可以省略不写
构造方法:无
成员方法:只能是抽象方法:存在默认修饰符:public abstract :可以省略不写
开发中,定义了一个接口
子实现类名都是在接口名的后面加上Impl
例:
定义一个接口
interface Inter{
...
}
class InterImpl implements Inter{
...
}
类与类,类与接口,接口与接口之间的关系
类与类,类与接口,接口与接口之间的关系
类与类之间:继承的关系 extends :支持单继承,不支持多继承,可以多层继承
类与接口之间:实现关系 implements:
一个类继承另一个类的同时,可以实现多个接口
接口与接口之间:继承关系 extends :可以单继承,也可以多继承
interface 接口名1 extends 父接口1,父接口2,...{}
抽象类和接口的区别?
抽象类和接口的区别?
抽象类和接口的区别?
1)成员的区别
成员变量:
抽象类:可以是变量,也可以常量(使用final关键字)
接口:只能是常量:存在默认修饰符:public static final(可以省略不写)
构造方法
抽象类: 有构造方法;无参/有参: 针对父类进行分层初始化
抽象类多态的形式: 抽象的父类名 对象名 = new 子类名() ;
接口:没有构造方法
成员方法:
抽象类:既可以是抽象方法(必须携带abstract),也可以是非抽象方法
接口:只能是抽象方法:存在默认修饰符:public abstract
2)关系的区别
类与类,类与接口,接口与接口之间的关系
类与类之间:继承的关系 extends :支持单继承,不支持多继承,可以多层继承
类与接口之间:实现关系 implements:
一个类继承另一个类的同时,可以实现多个接口
接口与接口之间:继承关系 extends :可以单继承,也可以多继承
interface 接口名1 extends 父接口1,父接口2,...{}
3)设计理念的区别
抽象类----体现的继承关系(类与类之间的关系居多),---描述 "is a"的关系
接口--- 实现关系:一个事物所具备的额外功能,---描述的是一种"like a"的关系
使用接口----使用接口多态---可以提高代码的扩展性!
Day5
带包的文件如何编译和运行
带包的文件如何编译和运行!
方式1:
手动方式编译
1)先在当前这个Java文件的所在目录中,对这个Java文件使用javac 文件名.java
2)编译完成之后产生一个 ".class" 文件
3)手动方式创建cmo.xxx.xxx文件夹 ,子文件夹
将2)产生的字节码文件放进去
4)运行这个类
java com.xxx.xxx.文件名
方式2:(推荐这种:带包的编译和运行)
自动方式编译
1)进入到当前java文件所在目录中,直接编译
编译改为javac -d . xxx.java
例如将javac Test.java--->改为--->javac -d . com.sc.Test.java
2)自动的将包名以及字节码文件 放在com/sc文件夹下面
3)运行这个类
java -d . com.sc.Test
四种修饰符的权限设置
import 包名.类名; //此时这个类的访问权限必须足够大,否则报错
不同包下:
1)导包
2)将导入的类:先进行编译
3)在当前类使用自定编译的方式:javac -d . xxx.java
4)带包的运行
public > protected >default>private
权限修饰符:
private:私有的
default默认修饰符
protected:受保护的
public:公开的,公共的,访问权限很大
本类 | 同包 | 非同包子类 | 其他包的子类 | |
---|---|---|---|---|
privat | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |