java的代码块分类
局部代码块:比较简单,在局部位置(方法定义中)定义的{},
作用:限定某个变量的生命周期
构造代码块:在类的成员位置
作用:在执行构造方法之前,如果存在构造代码块,优先执行构造代码块
可以将构造方法中共性内容,放在构造代码中!(优先级:构造代码块>构造方法)
静态代码块
static{},在类的成员位置,类一加载,静态代码块先执行
类就加载一次,静态代码块也就执行一次就完毕!
一个类中如果有静态代码块,构造代码块,构造方法
静态代码块>构造代码块>构造方法
什么是构造方法
1)方法名和类名一致
2)没有具体返回值类型
3)连void都没有
构造方法是支持方法重载的(方法名相同,参数列表不同,与返回值无关)
使用构造方法的注意事项
1)一个类中如果没有提供任何构造方法,系统会默认提供一个无参构造方法,
2)如果一个类中提供了有参构造方法,系统不会提供无参构造方法,如果你还要使用无参构造方法来创建对象,报错
类名 对象名 = new 类名();默认执行无参构造方法
给成员赋值的两种方式;
1)给setxxx赋值
2)给有参构造函数赋值
关于将变量定义的使用问题
什么是将变量定义为成员变量
如果这个需求能够描述现实世界事物的属性,这个时候才能将变量定义为成员变量,剩下的全部都是局部变量!
因为局部变量他的生命周期:随着方法调用而存在随着方法调用结束而消失
static关键字
java提供了关键字static ,本身的含义"共享的,共用的"(随着类的加载而加载)
特点:1)随着类的加载而加载
类在加载的时候,静态相关的成员(类成员:静态的变量或者静态的方法),随着类的加载而先进内存(静态区)
2)优先于对象存在,不能和this共存
3)static能体现"共享,共用"的意思
如果需求中有"共用"含义,这个变量直接使用static修饰
4)被static修饰的成员(变量/方法),推荐的访问方式时使用
类名,变量名
类名.静态方法名 ();
在使用静态相关变量/方法时的注意事项
1)非静态的方法,既可以访问静态的,也可以访问非静态的(要么访问静态变量/静态的方法)
2)静态只能访问静态的东西(静态变量/调用静态方法)
成员变量和静态变量的区别
1)存储位置不同
成员变量:堆内存汇总
静态变量:static静态区
2)生态周期不同
成员变量:随着对象的创建( 类名 对象名 = new 类名(); )而存在,随着对象的创建完毕等待垃圾回收而消失(不会立即回收,等到GC空闲的时候回收)
静态变量:随着类的加载而存在,随着类的加载完毕而消失
3)初始化不同
成员变量:它可以不初始化,存在默认初始化,通过set(xxx)或有参构造方法显示初始化
静态变量:也可以不初始化,或者直接初始化,也可以类名.变量名赋值;
4)访问方式不同
成员变量; 创建对象 类名.对象名=new 类名 对象名.成员变量
静态变量: 不推荐使用对象名来访问, 使用类名.变量名
继承
继承的含义:将多个类的共性内容抽取到一个独立的类中,这个类和其他类之间产生一种关系,成为继承,关键字"extends"
格式:
class 父类名{
共性内容:属性私有化
对外提供公共的访问方法
}
class 子类名 extends 父类名{
}
继承的特点
好处:
1)提高了代码的复用性
2)提高了代码的维护性(方便后期维护)
3)类与类产生的继承关系,是多态的前提条件
弊端:
继承的关系:是存在局限性的,不要为了使用部分功能而去使用继承!
继承的特点:类与类之间的关系,只支持"单继承"
不支持多继承,但是可以"多层继承"
什么时候使用继承?
如果一个类A是类B的一种,或者B类是A类的一种,这个时候使用"继承""
所有开发原则(接口分离/迪米特/开闭原则/依赖倒置…)都必须遵循: “低耦合,高内聚”(核心原则)
耦合:就是类和类的关系,越少越好 (耦合度只能降低,不能去避免!)
内聚: 某一个类完成某件事情能力!(一个类能完成,尽量一个类去完成!)
继承的注意事项
1)子类继承父类,继承父类的非私有的成员;私有的成员,可以间接访问
2)子类继承父类,构造方法是不继承的,通过一个关键字来访问 super()
继承的成员变量访问问题
1)子类继承父类,如果子类和父类的成员变量名称不一致,(分别访问即可)
2)子类继承父类,子类和父类的成员变量名称一致,访问(采取"就近原则")
就近原则机制
1)首先现在子类的局部位置(成员方法)找,如果有,就使用
2)如果子类的局部位置没有,那么就在子类的成员位置中找,有就使用
3)如果子类的成员位置也没有,那么就在父类的成员位置中找,有就使用,
4)如果父类也没有,继续往他的父类上找,最终顶层父类中都没有,那么报错(找不到这个变量!)
继承的构造方法访问问题:super来访问
- 构造方法目的:就是类的成员进行数据初始化!
*
- 继承关系中,子类不能继承父类的构造方法,但是可以间接通过super()来访问,为什么子类中构造方法默认是这种机制呢?
*
- 子类的所有构造方法都默认访问父类的无参构造方法(子类的所有构造方法的第一句话super();,可以省略不写), 因为:jvm 校验语法的时候, class Zi extends Fu{}
- 存在继承关系,需要让父类先初始化,因为子类可能会用父类的数据,所以采用"分层初始化!"
*
-
面试题:继承关系中, 父类的中如果没有无参构造方法(存在有参构造方法),子类会出现什么情况?如何解决呢?
*
- 子类全部报错,子类的所有构造方法都默认访问父类的无参构造方法(子类的所有构造方法的第一句话super();,可以省略不写)
*
- 1)解决方案1:永远给出类的无参构造方法
- 2)如果现在不给出父类无参构造方法,如何解决呢?
- 让子类的所有构造方法显示的访问父类的有参构造方法!(只要父类出现初始化 :执行构造方法就是初始化)
*
- 3)子类的所有构造方法中的某一个只要能够让父类初始化即可
继承的成员方法访问问题
子类继承父类,如果子类和父类的成员方法名称不一致,分别调用即可
如果一致,而且一模一样,方法重写 override(方法覆盖/重写) 重写的时候必须保证他的访问权限足够大!
什么是方法重写
继承中使用的,子类出现了和父类一模一样的方法,目的是为了将父类的方法重写,
- 注意事项:
- 重写的时候,子类的方法访问权限不能更低!
final关键字的特点
- 在有的时候,子类继承父类, 在父类不想让子类将父类的方法重写,为了保证数据的安全性!
- java提供了关键字:final(状态修饰符):最终的,无法更改的
1)可以修饰类,该类不能被继承
2)修饰成员变量,此时这个变量是常量,必须赋值!这个变量只能赋值一次! (自定义常量)
实际开发中:static和final 一块的
3)final也可以修饰成员方法,此时这个成员方法不能被重写.
4)final修饰引用类型,此时引用类型的地址不能再改变了(不能重新再创建对象了)
- 面试题
- final修饰基本数据类型和修饰引用类型区别?
- 被final修饰的基本数据类型,它的数据值不能再改变了(不能在赋值了)
- 被final修饰的引用数据类型,它的空间地址值不能在改变了(不能重新在new了)
this和super的区别
概念区别
this:代表的当前类的地址值引用
super:代表父类的空间表示
使用不一样:
this.变量名:访问本类的成员变量
super.变量名:访问父类的成员变量
this.方法名:访问本类的成员方法
super.方法名:访问父类的成员方法
this();:访问本类构造,必须放在本类构造的首行
super():访问父类构造必须放在子类构造的首行
其他区别this表示当前对象,super不能表示当前对象
引入概念—多态
多态的概念
多态:能体现事物的多种形态
从现实世界事物中考虑:“多态” 一种事物多种形态!
java面向对象中(程序中) “多态” : 一个类体现出内存的变化
多态的前提条件
1)必须有继承关系
2)必须存在方法重写
3)必须存在父类引用指向子类对象
格式:
父类名 对象名 = new 子类名() ;
多态的成员访问的特点
1)访问成员变量:编译看左,运行看左
2)访问成员方法:编译看左,运行看右!
静态的方法:算不上方法重写,这种跟类相关,类一加载就可以直接使用(类名.方法名())
3)构造方法:由于存在继承,构造方法在执行的时候,分层初始化,先让父类初始化,然后再是子类进行构造初始化!
多态的好处
1)可以提高代码的扩展性(父类引用指向子类对象 Fu fu = new Zi()) 多态保证的(重点)
2)可以提高代码的复用性以及维护性(由继承保证的)
多态的弊端
父类引用指向子类对象, Fu fu = new Zi() ; 这种格式无法访问子类的特有功能
解决方案:1)直接创建子类对象 子类名 对象名 = new 子类名 ();
虽然可以但是需要重新开辟堆内存空间(消耗内存空间)内存角度考虑不太好
2)推荐:向下转型
将父类引用强转为子类引用!------就是我们基础"强转类型转换"(将大类型转换为小类型)
父类名 父类的引用 = new 子类名 (); 向上转型
子类名 对象名 =(子类名)父类的引用; 向下转型 —前提必须有向上转型
如果向下转型(将父类引用强转为子类引用),使用不当(),会导致程序出现异常 "ClassCastException"类转换异常
abstract关键字(抽象)
什么是抽象类?
一个事物的某个行为应该具体的事物具体的体现,将这个事物定义为"抽象"
有抽象方法的类一定是抽象类!
抽象类不一定有抽象方法(重点)
抽象方法的格式:
权限修饰符 abstract 返回值类型 方法名(无参/有参)
抽象类的特点
1)抽象类不能创建对象;不能实例化
2)抽象类的子类如果也是抽象类,不能实例化,一定会提供最具体的子类 完成实例化,
抽象的父类 对象名 = new 具体的子类名();
抽象的成员特点:
成员变量:既可以变量,也可以是常量;
成员方法:既可以存在抽象方法(必须强转子类重写),也可以定义非抽象方法
构造方法:无参构造/有参构造都可以存在, 构造方法都需要让父类先初始化,然后再是子类进行初始化!
面试题
如果一个类没有任何一个抽象方法,把这个类定义为抽象方法的意义?
意义就是不让外界类直接创建对象(抽象类不能创建对象),需要提供具体的子类进行实例化!
abstract和那些关键字冲突?
private:被private修饰的成员需要在当前类 进行访问,而如果加入abstract,强转子类完成
final: 被final修饰的成员方法,不能重写!而abstract抽象方法,必须强转子类重写
static:被static修饰的成员方法,算不上重写…
abstract关键字的应用范围
1)定义类----抽象类
2)定义方法----抽象方法
接口
什么是接口?
接口体现的是这个事物本身不具备的功能,额外的功能;
接口定义------Java代码定义 关键字 interface
interface 接口名{} 接口名标识符--------->和类名起名一致"大驼峰命名法"
要实现接口里面的额外功能----------->才具备这功能
开发中定义接口实现类名
class 类名+Impl implements(实现) 接口名{
}
接口有什么特点?
1)接口的方法不能有方法体,只能是抽象方法 而且隐藏了public abstract(可以省略不写)
2)接口不能实例化,(不能创建对象)
3)如果接口的实现类它是一个抽象类(不能实例化),肯定有一个具体的接口来进行new对象
接口名 对象名 = new 具体的子实现类() ; 借口多态
接口的成员特点
成员变量:在接口中成员变量只能是常量-------存在默认修饰符 public static final(可以省略不写)
成员方法:只能是一个抽象方法,----------存在默认修饰符 public abstract(可以省略不写)
接口没有构造方法;
(面试题)接口和抽象类的区别?
类和接口的关系:实现关系
1)成员的区别:
抽象类:
成员变量:既可以是常量,也可以是变量
成员方法:既可以是抽象方法,也可以是非抽象方法
构造方法:无参/有参都存在,子类父类继承,需要分层初始化
接口:
成员变量:只能是常量
成员方法:只能是抽象方法
无构造方法
2)关系的区别
类与类:可能是一些抽象类,继承关系,只支持单继承,不支持多继承,但是可以多继承
类与接口:实现关系 implements
一个类继承另一个类(可能也是抽象类)的同时,还可以实现多个接口
接口与接口:继承关系 支持但继承,可以多继承,多层继承
3)设计理念的区别
抽象类–不能实例化
需要通过具体的子类实现类(继承关系)
核心设计理念体现都是一种"is a"的关系(xxx是XX的一种)
package在开发中应用含义
含义:本质就是文件夹(目录);程序员在编写代码存储的地址
包---------开发中(公司域名反写,多个包中间 . 隔开)
包------为了维护代码结构的(代码分层)
Java实体类(满足JavaBean规范)
1)这个类是具体类
2)属性私有化
3)对外提供公共的setxxx/getxxx
权限修饰符的范围
同一个包下的同一个类中 同一个包下子类中/无关类中 不同包下子类 不同包无关类
私有修饰符 private Y
默认修饰符 Y
受保护的 protected Y Y Y
公共的public Y Y Y Y
私有的修饰符private:权限最小(开发中,也就是定义实体类(描述现实世界事物))
关于类与类,类与接口,接口与接口的关系!
Java中最基本的单元就是类------Java中只支持单继承(类和类)
类与类:只支持单继承,不支持多继承,但是可以多层继承
类与接口:是实现关系,一个类继承另一个类的同时,可以实现多个接口
class 子类名 extends 父类名 implements 接口1,接口2…{}
接口与接口:继承关系;不仅可以单继承,还可以多继承
形式参数问题和返回值的问题----->只研究引用类型
数组--------->需要传递数组对象
类
具体类----->实际参数,需要传递当前类对象
抽象类----->抽象类不能实例化,实际参数需要传递该抽象类的子类对象(抽象类多态)
接口--------->接口不能实例化,实际参数需要传递该接口的子类实现类对象(接口多态)
方法的返回值类型问题:
1)返回值基本类型:需要什么基本数据类型,使用对应的类型接受
2)研究引用类型:
类
具体类:需要返回的是当前具体类的对象
抽象类:需要返回的是当前抽象类的子类对象
接口:需要返回的是接口的子实现类 对象
内部类(了解)
内部类------实际开发中(应用层面居多)
内部类里面的一些访问方式
属于设计层面
内部类:一个类a中,有一个类b,将类b就称为类a的内部类,类a就是类b的外部类1
内部类的两种格式
1)成员内部类---->在一个外部类的成员位置(类中,方法外)定义的类
特点:成员内部类可以访问外部类的成员,包括私有相关的!
成员内部类的修饰符
可以有private修饰,目的是为了数据的安全性
可以static修饰,
静态的成员内部类只能访问外部类的静态成员!
静态的成员内部类中无论是静态方法还是非静态方法:访问外部类的成员必须静态!
想直接通过外部类来访问静态成员内部类的成员信息,访问格式:
外部类名.内部类名 对象名 = new外部类名.内部类名();
对象名.静态成员内部类的成员;
如何直接通过外部类去访问内部类的成员呢?(格式 )
外部类.内部类 对象名 = new 外部类名().new 内部类名();
对象名.成员内部类的成员;
内部类的面试题
内部类和外部类:没有继承关系
局部内部类---->在外部类的局部位置(方法定义中)定义的类
特点:和成员内部类一样,局部内部类也可以直接访问外部类的包括私有
面试题
局部内部类访问它的成员方法里面的局部变量,局部变量有什么特点?
局部变量它随着方法的调用而存在,随着方法调用的结束而消失,但是现在是通过局部对象调用它的成员方法还在使用这个局部变量
局部变量必须为常量------局部内部类对象不会立即消失,等待gc回收
匿名内部类
含义:没有名字的类
应用范围:在局部位置中(方法定义中或者声明上)
格式 new 新建的抽象类名/接口名(){
重写抽象类或者接口方法(){
....逻辑
}
}
匿名类的本质:继承了该类或者是实现了该接口的子类对象
常用类(掌握jdk提供的常用类的常用功能)
java.lang.Object------>所有类的父类(jdk提供的类/我们自定义的类)
equalsz():建议所有的子类必须重写---->不重写,引用类型比较地址值是否相等
底层源码用的就是 ==
toString():建议所有子类必须重写这个方法
get
常用类
重要的几个类
java.lang.Object类
表示所有的类的根类(超类或者父类),所有的类默认继承Object,拥有这个类的所有私有方法
public final class getclass():获取任何Java类型的字节码文件对象(返回值表示正在运行的那个类)
面试题:在java中获取一个类的字节码文件对象得方式有几种
三种方式
public final Class getClass() 任意java对象调用getclass()
任意java类型的class属性
class类有一个静态方法forName(“包名.类名”)
String(里面功能最多
转换
)
StringBuffer(线程安全的类)
java,util,Date 日期类
String日期文本
基本类型的四类八种------>八个引用类型(Inetger, Character)
选择排序
数组角标从开始,将它对应元素依次和后面的元素比较,将小的往前放,第一次比较完毕后最小值就出现在最小索引出!依次这样比较,可以得到一个排好序的数组
//定义一个选择排序的方法
public static int[] selectSort(int[] arr){
for(int x = 0 ; x < arr.length - 1;x++){//比较的次数
for(int y = x+1; y < arr.length;y++){ //元素进行判断 比较
//如果前面的元素比较后面元素大,将后面的元素往前放
if(arr[x] > arr[y]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
}
return arr;
}
//遍历数组
for(int x = 0 ; x < arr.length ; x++){
if(x==arr.length-1){
//取到最大索引值,对应最后一个元素
s+=arr[x] ;
s+="]" ;
}else{
//中间角标对应的元素
s+= arr[x] ;
s+=", ";
}
}
return s;
}