Java初级
1.this关键字的使用
this调用的结构:属性,方法,构造器
this调用属性或方法时,理解为 当前对象或正在创建的对象
this调用构造器:this,声明首行,只能有一个,表示调用当前类中其他的重载构造器
class User{
public User(){}
public User(String str){
this();//表示调用public User(){}
}
public User(String str,int a){
this(str);//表示调用public User(String str){}
}
}
2.继承性
优点:
减少了代码的冗余,提高了通用性
提高了扩展性
为多态的使用,提供了前提(子类的多态性)
特点:
局限性:类的单继承性,后续通过接口解决
支持多层继承
理解:
子类获取了父类全部属性方法,可能受封装性的影响,不能直接调用
① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方 式调用父类指定的构造器。
② 规定:“super(形参列表)”,必须声明在构造器的首行。
③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载 的构造器, 结合②,结论:在构造器的首行,"this(形参列表)" 和 "super(形 参列表)"只能二选一。
④ 如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用 "super(形参列表)", 则子类此构造器默认调用"super()",即调用父类中空参的 构造器。
⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构 造器,要么会调用父类的构造器。 只能是这两种情况之一。
⑥ 由⑤得到:一个类中声明有 n 个构造器,最多有 n-1 个构造器中使用了 "this(形参列表)",则剩下的那个一定使用"super(形参列表)"。
3.方法的重载与重写
方法的重载:
前提条件:首先是位于一个类之中或者其子类中
方法名必须相同;方法的参数列表一定不一样;访问修饰符和返回值类型可以相同也可以不同
方法的重写:
前提条件:子类继承父类,重写父类方法
方法名相同,参数相同,但是具体的实现不同
class Father{
public void method(int i){
System.out.println("Father.method");
}
}
class Son extends Father{
public void method(int i){//重写
System.out.println("Son.method");
}
}
class Daughter extends Father{
public void method(int i,int j){//重载
System.out.println("Daughter.method");
}
}
方法签名的组成
1、方法名
2、参数列表(形参类别、个数、顺序)
特别注意:
1、与返回值、修饰符以及异常无关
2、在Class文件格式之中,返回值不同,可以合法地共存于一个Class文件中。
常见的问题应用:重载和重写。
重载:同一个类中方法签名不同的方法。
重写:方法签名必定相同,返回值必定相同, 访问修饰符 子 > 父, 异常类 子 < 父
4.super关键字
调用属性,方法,构造器
在子类构造器中,首行要么使用了this(形参列表),要么使用了super(形参列表)
5,子类对象实例化
子类调用构造器创造对象时,一定会直接或间接调用父类构造器,直到调用到Object()构造器
6.多态性
定义:
狭义上的理解:子类对象的多态性
广义上的理解:子类对象的多态性,方法的重写 (编译和运行不一致,称为多态性)
格式:
Object obj=new String()
前提:
类的继承、方法的重写
优点:
减少了大量重载方法的定义
开闭原则:扩展开放,修改关闭
使用:
虚拟方法调用:"编译看左边,运行看右边"; 属性不存在多态性; 不能调用子类特有方法,如果要调用,就向下转型,使用强转可能出现ClassCastException类型转换异常,用instanceof关键字进行判断
7.Object类的使用
Object中的功能
没有属性,只有空参构造器和方法
getClass()\hashCode()标识\notify()唤醒以及notifyAll()\wait()
①x.clone!=x复制值,不是地址
也就是会创建新的对象
②hashcode()
public int hashCode():返回每个对象的 hash 值。
③getClass()
public final Class<?> getClass():获取对象的运行时类型
④finalize() 通知销毁,并不是立即销毁,在 JDK 9 中此方法已经被标记为过时的。
重点:equals() toString()
⑤equals
Date now=new Date();
System.out.println(“now=”+now); //相当于
System.out.println(“now=”+now.toString());
8.native关键字
使用 native 关键字说明这个方法是原生函数,也就是这个方法是用 C/C++等非
Java 语言实现的,并且被编译成了 DLL,由 Java 去调用
9.构造方法
/*
* 在字节码文件中,构造器以<init>方法的形式存在,每个<init>方法都对应一个类的构造器,该方法用于初始化当前创建的对象的信息,
* 内中包含了实例变量的显式赋值,代码块的赋值和构造器中的代码
* 类的加载从父类开始,由父及子 静态先行
* */
Java中级
1.关键字:static
static:静态的,随着类的加载而加载
用来修饰:属性 方法 代码块 内部类
类的生命周期中只有一个
//static 静态的 内存中只有一份 随着类的加载而加载 静态方法中只能调用静态属性 静态方法
//修饰的结构:属性 方法 代码块 内部类
//变量的分类:
// 1.按照数据类型:基本数据类型,引用数据类型
// 2.按照类中声明的位置:
// 成员变量:
// 按照是否使用static修饰:
// 静态变量(类变量):jdk6及之前,存放在方法区,之后在堆
// 非静态变量(实例变量):堆
// 局部变量:方法内、方法形参、构造器内、构造器形参、代码块内
//static修饰的方法中不能使用this和super
//开发中,什么时候需要将属性/方法声明为静态的
// 1.属性共享
// 2.常量
// 3.操作静态属性
// 4.工具类
2.单例模式:在整个软件系统中,只存在唯一实例,即对某 个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
class Singleton {
// 1.私有化构造器
private Singleton() {
}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single = new Singleton();
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
return single;
}
}
class Singleton {
// 1.私有化构造器
private Singleton() {
}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single;
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
if(single == null) {
single = new Singleton();
}
return single;
}
}
设计模式
3.关键字:final
修饰:类 方法 变量
不能被继承,没有子类:例如:String 类、System 类、StringBuffer 类
不能被重写
常量:如果某个成员变量用 final 修饰后,没有 set 方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值
4.关键字:abstract
修饰:类 方法
抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
设计模式: 模板方法设计模式(TemplateMethod)
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
5.静态代码块 普通代码块 构造器
/*
*类中可以声明的结构:属性 方法 构造器 代码块 内部类
* 代码块:
* 1.作用:用于初始化类或对象的信息(即初始化类或对象的成员变量)
* 2.代码块的修饰:只能使用static
* 3.分类: 静态代码块
* 非静态代码块
* 4.使用:
* 静态代码块:随着类的加载而执行,由于类只会加载一次,所以执行一次
* 用于初始化类的信息
* 非静态代码块:随着对象的创建而执行,每创建一次实例,就执行一次
* 用于初始化对象的信息
* 5.默认初始化 显式初始化/代码块初始化 构造器初始化 对象赋值
* */
6.实例变量赋值顺序
7.接口
[修饰符] interface 接口名{
//接口的成员列表:
// 公共的静态常量
long MAX_SPEED = 500*1024*1024;//500MB/s
// 公共的抽象方法
void in();
void out();
// 公共的默认方法(JDK1.8 以上)
default void start(){
System.out.println("开始");
}
// 公共的静态方法(JDK1.8 以上)
static void show(){
System.out.println("USB 3.0 可以同步全速地进行读写操作");
}
// 私有方法(JDK1.9 以上)
}
接口中没有构造器,没有初始化块,因为接口中没有成员变量需要动态初始化。
注意:
1.接口的多实现:
接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。
2.接口多继承:
一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子接口继承父接口的方法。
3. 接口与实现类对象构成多态引用
4.使用接口的静态成员
接口不能直接创建对象,但是可以通过接口名直接调用接口的静态方法和静态常量。
public interface Friend {
default void date(){
System.out.println("吃喝玩乐");
}
}
public class Father {
public void date(){
System.out.println("爸爸约吃饭");
}
}
public class Son extends Father implements Friend {
@Override
public void date() {
//(1)不重写默认保留父类的
//(2)调用父类被重写的
// super.date();
//(3)保留父接口的
// Friend.super.date();
//(4)完全重写
System.out.println("跟康师傅学 Java");
}
}
public interface Friend {
default void date(){
System.out.println("吃喝玩乐");
}
}
public interface BoyFriend {
default void date(){
System.out.println("神秘约会");
}
}
//选择保留其中一个,通过“接口名.super.方法名"的方法选择保留哪个接口的默认方法
public class Girl implements Friend,BoyFriend{
@Override
public void date() {
//(1)保留其中一个父接口的
// Friend.super.date();
// BoyFriend.super.date();
//(2)完全重写
System.out.println("跟康师傅学 Java");
}
}
8.内部类
* Thread类,内部声明了State类,表明线程的生命周期 * HashMap类中声明了Node类,表示封装的key和value * 分类: * 成员内部类:声明在外部类里面 * 静态成员内部类 * 非静态成员内部类 * 局部内部类:声明在方法内,构造器,代码块内 * * 成员内部类: * 1.理解: * 从类的角度看 * 可以声明属性、方法、构造器、代码块、内部类。 * 可以声明父类,可以实现接口 * 可以使用final abstract修饰 * 从外部类的成员角度: * 在内部可以调用外部类的属性和方法等结构 * 可以使用四种权限修饰符进行修饰(外部不能用private) * 2.如何创建成员内部类的实例
9.枚举类
开发中,如果针对于某个类的对象是确定个数的,则声明为枚举类
类的对象有限,固定的几个,不能让用户随意创建
– 星期:Monday(星期一)......Sunday(星期天)
– 性别:Man(男)、Woman(女)
– 月份:January(1 月)......December(12 月)
– 季节:Spring(春节)......Winter(冬天)
– 三原色:red(红色)、green(绿色)、blue(蓝色)
– 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)
– 就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)
– 订单状态:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、 Delivered(已发货)、Checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)
– 线程状态:创建、就绪、运行、阻塞、死亡
在 JDK5.0 之前如何声明枚举类呢?
• 私有化类的构造器,保证不能在类的外部创建其对象
• 在类的内部创建枚举类的实例。声明为:public static final ,对外暴露这些常量对象
• 对象如果有实例变量,应该声明为 private final(建议,不是必须),并在构造器中初始化
class Season{
private final String seasonName;
private final String seasonDesc;
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
public static final Season SPRING=new Season2("春天","春暖花开");
public static final Season SUMMER=new Season2("夏天","夏日炎炎");
public static final Season AUTUMN=new Season2("秋天","秋风送爽");
public static final Season WINTER=new Season2("冬天","白雪皑皑");
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
public static void main(String[] args) {
/*
*
*使用enum定义的枚举类,继承于Enum类,提供了一些方法:
* 1.toString()
* 2.name()
* 3.values()
* 4.valueOf(String name)
* */
System.out.println(Season.SPRING.name());//SPRING常量名称 SPRING
// A|T+Enter自动生成,补全
Season[] values=Season.values(); //SPRING...WINTER
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
}
Season spring = Season.valueOf("SPRING"); //SPRING
System.out.println(spring);
System.out.println(Season.SPRING); //SPRING
System.out.println(Season.SPRING.getSeasonName());
System.out.println(Season.SPRING.getSeasonDesc());
Season1.SPRING.method();
Season2.SPRING.method();
}
interface Info{
void method();
}
enum Season1 implements Info{
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋风送爽"),
WINTER("冬天","白雪皑皑");
private final String seasonName;
private final String seasonDesc;
Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//情况一:枚举类实现接口,在枚举类内实现接口的抽象方法,通过不同枚举调用,执行同一个方法
@Override
public void method() {
System.out.println("这是一个抽象方法");
}
}
enum Season2 implements Info{
//情况二:每个对象实现
SPRING("春天","春暖花开"){
@Override
public void method() {
System.out.println("春天在哪里");
}
},
SUMMER("夏天","夏日炎炎"){
@Override
public void method() {
}
},
AUTUMN("秋天","秋风送爽"){
@Override
public void method() {
}
},
WINTER("冬天","白雪皑皑"){
@Override
public void method() {
}
};
private final String seasonName;
private final String seasonDesc;
Season2(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
}
10.注解
11.包装类
/*
* 方法的参数传递机制:
* (1)基本数据类型:形参的修改完全不影响实参
* (2)引用数据类型:通过形参修改对象的属性值,会影响实参的属性值
* 这类 Integer 等包装类对象是“不可变”对象,即一旦修改,就是新对象,和
实参就无关了
*/
public static void change(int a ,Integer b,Circle c ){
a += 10;
// b += 10;//等价于 b = new Integer(b+10);
c.radius += 10;
/*c = new Circle();
c.radius+=10;*/
}
包装类的缓冲对象:存在方法区
Integer a = 1;
Integer b = 1;
System.out.println(a == b);//true
Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false
Integer m = new Integer(1);//新 new 的在堆中
Integer n = 1;//这个用的是缓冲的常量对象,在方法区
System.out.println(m == n);//false
Integer x = new Integer(1);//新 new 的在堆中
Integer y = new Integer(1);//另一个新 new 的在堆中
System.out.println(x == y);//false
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1==d2);//false 比较地址,没有缓存对象,每一个都是新new 的
类型转换问题:
Integer i = 1000;
double j = 1000;
System.out.println(i==j);//true 会先将 i 自动拆箱为 int,然后根据基本数
据类型“自动类型转换”规则,转为 double 比较
Integer i = 1000;
int j = 1000;
System.out.println(i==j);//true 会自动拆箱,按照基本数据类型进行比较
Integer i = 1;
Double d = 1.0
System.out.println(i==d);//编译报错
其他API
Double.compare(double d1, double d2)
Integer.compare(int x, int y)
Character.toUpperCase('x');
Character.toLowerCase('X');
12.Arrays工具类
/*
* Arrays工具类的使用:
*数组排序:
– static void sort(int[] a) :将 a 数组按照从小到大进行排序
– static void sort(int[] a, int fromIndex, int toIndex) :将 a 数组的[fromIndex,
toIndex)部分按照升序排列
– static void sort(Object[] a) :根据元素的自然顺序对指定对象数组按升序进
行排序。
– static void sort(T[] a, Comparator<? super T> c) :根据指定比较器产生的
顺序对指定对象数组进行排序。
*数组元素的二分查找:
– static int binarySearch(int[] a, int key) 、static int binarySearch(Object[] a,
Object key) :要求数组有序,在数组中查找 key 是否存在,如果存在返回
第一次找到的下标,不存在返回负数。
*数组元素拼接:(打印用的)
– static String toString(int[] a) :字符串表示形式由数组的元素列表组成,括
在方括号("[]")中。相邻元素用字符 ", "(逗号加空格)分隔。形式为:
[元素 1,元素 2,元素 3。。。]
– static String toString(Object[] a) :字符串表示形式由数组的元素列表组
成,括在方括号("[]")中。相邻元素用字符 ", "(逗号加空格)分隔。元
素将自动调用自己从 Object 继承的 toString 方法将对象转为字符串进行拼
接,如果没有重写,则返回类型@hash 值,如果重写则按重写返回的字符
串进行拼接。
*
* */
13.IDEA快捷键
/*
*
* 智能提示(代码补全):A|T+Enter
* get/set/构造器:alt+Insert
*
* 复制删除特定行:ctrl+D/Y
* 重写父类方法:ctrl+o
* 实现接口方法:ctrl+i
* 方法参数提醒:ctrl+p
* 自动生成返回值变量:ctrl+alt+v
* 使用xx环绕surround with...:ctrl+alt+t
* 格式整理:ctrl+alt+l
* 批量导包:ctrl+alt+o
* 抽取代码重构方法:ctrl+alt+m(很神奇)
*
* 切换到上一行代码空位:ctrl+alt+Enter
* 切换到下一行代码空位:shift+Enter
* 代码移动:ctrl/alt+shift+上/下
*
* 反撤销:ctrl+shift+z
* 选中结构大小写转换:ctrl+shift+u
* 批量修改变量名、方法名、类名:shift+F6
*
*
*
* */