构造方法
-
方法名和类名一致
-
没有具体的返回值
-
没有void
构造方法支持重载
重载:方法名相同,参数列表不同,与返回值无关
格式:
public 类名(){ } public 类名(形式参数){ }
使用构造方法的注意事项
-
一个类中没有提供任何构造方法,系统会默认提供一个无参构造方法
-
如果一个类中提供了有参构造方法,系统不会给给出无参构造方法,如果要使用无参构造方法,系统会报错
类名 对象名 = new 类名();默认执行无参构造方法
给成员变量的赋值方式
setXXX(XX)赋值
有参构造赋值
class a{ private int b; public void setB(int b){ this.b=b; } public int getB(){ return b } }
有参构造方法的作用
有参构造方法可以在创建对象的同时为每个属性赋值
class A{ private int b; private int c; public A(int b,int c){ this.b=b; this.c=c; } public static void main(String[] args){ A b=new A(10,20); } }
成员变量和局部变量的定义时间
如果这个事物可以描述现实世界事物属性,这个时候定义为成员变量,其他均为局部变量
局部变量随着方法的调用存在,随着方法的调用结束而消失
static
特点
-
随着类的加载而加载,类在加载的时候,static修饰的成员随着类的加载而先进内存
-
static优先于对象存在,不能和this共存
-
static是共享,共存的意思,如果需求中有共享的意思,这个变量直接用static修饰
-
被static修饰的成员直接用类名.变量名/类名.方法名()直接访问
class A{ static int b;//静态变量 int c;//非静态变量 public static void C(){//静态方法 System.out.println(""); } } class D{ public static void main(String[] args){ A a=new A();//创建对象 a.c=10; A.b=20;//类名.变量名 A.C();//类名.方法名() } }
注意事项
静态的方法只能访问静态的
非静态的可以访问静态的,也可以访问非静态的
class A{ int b; static int c; public void d(){ Systen.out.println(b); System.out.println(c); } public static void e(){ Systen.out.println(c);//静态的e()不能访问非静态的b } public static void f(){ e();//静态的f()不能访问非静态的d() } } class Test{ public static void main(String[] args){ A a=new A(); a.d();//对象名调用非静态方法 A.e();//类名调用静态方法 A.f(); } }
数组工具类
-
针对数组的工具类,会提供针对数组各种各样的操作
-
工具类中,构造方法私有化,对外提供静态的公共方法
-
构造方法私有化可以不让外界创建对象
构造代码块{}
-
局部代码块:定义在局部位置,可以限定某个变量的生命周期
-
构造代码块:在类的成员位置,在执行构造方法之前,执行构造代码块,可以将构造方法的共性内容放到构造代码块
-
静态代码块:static{},在类成员的位置,类一加载,静态代码块先执行,类就加载一次,静态代码块就执行一次
优先级:静态代码块 > 构造代码块 > 构造方法
继承
将多个事物的共性提取到一个独立的事物中,这个事物和其他事物之间产生的一种关系成为继承
格式:
class 父类名{ 共性内容:属性私有化 对象提供公共类的访问方法 } class 子类名 extends 父类名{ }
继承的优点
-
提高代码的复用性
-
提高代码的可维护性
-
类与类产生的继承关系是多态的前提条件
继承的特点
继承可以单继承,不能多继承,但是可以多层继承
继承的弊端
-
继承存在局限性,不能为了实现部分功能而使用继承,代码的耦合会变高
-
一个类是另一个类的一种时使用继承
开发原则
高内聚,低耦合
耦合:就是类与类的关系越少越好
内聚:某一个类完成某件事的能力
注意事项
-
子类继承父类,只能继承父类的非私有成员,私有的成员可以间接访问
-
子类继承父类,构造方法是不能被继承的,只能间接访问,可以通过super访问
class Fu{ private int a=10; int b=20; private void show1(){//私有的不能调用共有的 System.out.println(""); } public void show2(){ show1();//同一个类中共有的调用私有的方法 System.out.println(a); } } class Zi extends Fu{ public static void main(String[] args){ Zi zi=new Zi(); zi.show2(); } }
继承中成员变量的问题
-
子类的变量名称和父类的变量名称不一致时,分别访问即可
-
如果子类和父类的变量名称一致,访问采取就近原则
就近原则:
-
首先先在子类的局部位置(成员方法)找,如果有,就使用
-
如果子类的局部位置没有,那么就在子类的成员位置中找,有就使用
-
如果子类的成员位置也没有,那么就在父类的成员位置中找,有就使用,
-
如果父类也没有,继续往他的父类上找,最终顶层父类中都没有,那么报错(找不到这个变量!)
super和this的区别
this:代表的当前类对象的地址值引用 super:代表父类的空间表示(父类的对象的地址值引用)
使用不一样
this.变量名:访问本类的成员变量 super.变量名:访问父类的成员变量
this.方法名() ;访问本类的成员方法 super.方法名();访问父类的成员方法
this() : 访问本类的无参构造方法 this(xx):访问本类的有参构造方法
super() :访问父类的无参构造方法 super (xx) :访问父类的有参构造方法
class Fu{ int a=10; } class Zi extends Fu{ int a=20; public void show(){ int a=30; System.out.println(a);//a=30 System.out.println(this.a)//a=20 System.out.println(super.a)//a=10 } }
构造方法的目的
类成员进行数据初始化
继承关系中,子类不能继承父类的构造方法,但是可以间接通过super访问,为什么子类构造方法默认这种机制?
子类所有的构造方法默认访问父类的无参构造方法(子类所有的构造方法第一句默认super();,可以省略不写),因为jvm校验的时候class Zi extends Fu{},存在继承关系,需要让父类先初始化,因此子类可能要用父类的数据,所以采用分层初始化
继承关系中,父类如果没有无参构造方法,存在有参构造方法,子类会出现什么情况
子类全部报错,子类所有构造方法默认访问父类的无参构造
(子类所有构造方法第一句话super,可以省略不写)
解决方案
-
永远给出类的无参构造
-
让子类所有构造方法显示的访问父类有参构造(只要父类出现初始化,执行构造方法就是初始化)
-
子类的所有构造方法中某一个只要能够让父类初始化
先执行子类的有参构造方法this,然后在子类的构造方法中先让父类初始化super
代码块的优先级
静态代码块 > 构造代码块 > 构造方法
继承关系中,构造方法的访问(分层初始化:先父类,后子类)
继承中成员方法的问题
如果子类和父类方法名不一样,分别调用即可
如果子类父类方法一模一样,子类会将父类的方法覆盖(方法重写)
方法重写
继承中子类和父类一模一样的方法,目的就是将父类的方法重写
重写的时候子类的访问权限不能更低
class FU{ void a(){ System.out.println("qwe"); } } class Zi extends Fu{ public void a(){ System.out.println("ert"); } } class Test{ public static void main(String[] args){ Zi zi=new Zi(); zi.a();//ert } }
final:最终的,无法更改的
被final修饰的成员变量,他的数据值不能再改变了
final关键字的特点
1)可以修饰类,该类不能被继承
2)修饰成员变量,此时这个变量时常量(自定义常量)
如果final修饰成员变量必须赋值!(基本类型)
被final:这个成员变量只能被赋值一次!
方法重写0verride和方法重载Overload的区别?
方法重载Overload: 定义方法的时候,多个方法的方法名相同,参数列表不同,与返回值无关(目的:提高了方法扩展性)
参数列表不同
1)参数个数
2)参数类型
3)先后类型顺序
方法重写0verride: 在继承中,子类出现了和父类一模一样的方法声明,子类会将父类的方法覆盖,使用子类的一些自己功能;|
重写的时候,要保证访问权限足够大!(重写的目的:为为沿用父类功能,然后还可以自己的优化的功能!
多态
1.多态的概念:能够体现事物的不同形态(程序中,内存的变化)
从现实世界事物中考虑:"多态" 一个事物多种形态
Java面向对象中(程序中)"多态":一个类体现出内存的变化
2.多态的前提条件:
1)必须有继承关系(如果没有继承关系,不谈多态)
2)必须存在方法重写
猫和狗都需要吃饭,吃的东西不-样(具体的动物类中应该给出具体体现)
3)必须存在父类引用指向子类对象
格式:
父类名 对象名 = new 子类名();(向上转型)
3.多态的成员访问特点:
1)成员变量:编译看左,运行看左!
2)成员方法:编译看左,运行看右!
静态的方法:算不上方法重写,和类相关,类一加载就可以直接使用(类名.方法名())
静态和类有关系,非静态和对象.
3)构造方法:由于存在继承,构造方法在执行的时候,分层初始化,先让父类初始化,然后再是子类进行构造初始化!|
4.多态的好处:
多态的好处: 1)可以提高代码的书^展性(父类引用指向子类对象Fu fu = new Zi()) 多态保证的 (重点) 2)可以提高代码的复用性以及维护性(继承保证的)
5.多态的弊端
父类引用指向子类对象,父类名 对象名= new 子类名 () ;(向上转型)这种格式无法访问子类的特有功能
解决方案:
1)直接创建子类对象 子类名 对象名 = new 子类名();
虽然可以,但是new子类名() ; 需要开辟堆内存空间(消耗内存空间) (内存角度 考虑不太好)
2)推荐:向下转型. 将父类引用强转为于类引用1----就是我们基础"强转类型转换”(将 大类型---小类型) int num=65; char c = (char)num ; // 'A' 父类名 父类的引用 = new子类名() ;向上转型 Fu f = new Zi() ; 子类名 对象名= (子类名)父类的引用;向下转型 Zi z = (Zi ) F;
abstract关键字(抽象)
什么是抽象类?
一个事物的某个行为应该具体的事物的具体体现,这个事物可顶层次(类)以定义"抽象
动物事物---都具备吃和睡的行为 只有见到具体的事物才具备的具体行为"猫", "狗"吃和睡不一样, 应该在具体事物中给出具体的体系,那么在 动物事物中,仅仅一个声明! (没有方法体)"
抽象类的定义:abstract class 类名{}
有抽象方法的类一定是抽象类,抽象类不一定都是抽象方法(重点)
抽象方法的格式:
权限修饰符abstract返回值类型方法名(空参/无参);
抽象类的特点:
1)抽象类不能进行实例化(不能创建对象)
抽象类不能new
2)抽象类的子类如果也是抽象类,不能实例化,一 定会提供最具体的子类完成实例化(创建对象) 抽象的父类名 对象名 = new 具体的子类名() ;抽象类多态
如果子类是抽象类,子类下面没有子类(没有任何意义)
抽象类的成员特点:
成员变量:
既可以是变量,也可以是常量
成员方法:
非抽象方法,不需要被子类重写
既可以存在抽象方法(不能省略abstract关键字,必须强转子类重写),也可以定义非抽象方法
构造方法:
无参构造/有参构造都可以存在,构造方法都需要让父类先初始化,然后再是子类进行初始化!
面试题: 如果一个 类没有任何抽象方法,把这个类定义为抽象类的意义? 意义就是:不让外界类直接创建对象(抽象类不能创建对象)----需要提供具体的子类进行实例化!
abstract在使用它和哪些关键字冲突
1)不能private一块用: 被private修饰的成员需要在当前类进行访问,而如果加入abstract,强转子类完成...
2)不能和final 一块用:被final 修饰的成员方法,不能被重写!而abstract抽象方法,必须强转子类重写
3)不能和static一块用: 被static修饰的成员方法,算不上重写..(抽象方法:非静态的,使用对象名来访问)
abstract关键字应用范围: 1)定义类---抽象类 2)定义方法--->抽象方法
什么是接口?
接口体现的是这个事物本身不具备的功能,额外的功能; 举例: 猫和狗----> 开始不具备 '跳高","钻火圈"--->驯养师---->训练猫和狗---->后天具备 "跳高", "钻火圈"
中国人---->经过后天学习"英语口语”----> 具备说"英语口语"的行为!
接口定义---Java代码定义 关键字 ipterface接口名{} 接口名标识符----> 和类名起名字-一致" 大驼峰命名法"
接口特点?
1)接口的方法不能有方法体,只能是抽象方法 而且隐藏public abstract(可以省略不写)
2)接口不能实例化(不能创建对象)
3)如果接口的实现类它是一个抽象类(不能实例化),肯定有一个具体的接口的实现类来进行new对象 接口名 对象名 = new具体的子实现类() ;接口多态
接口不能new,但是接口的具体的子实现类是可以new, 接口多态(实际开发中非常引
要实现接口里面的额外功能---->才具备这功能 开发中定义接口的实现类(子类 )名. class 接口名+ImpZ implements 接口名{ }
接口的成员特点:
成员变量:只能是常量--- 存在默认修饰符public static final( 可以省略)
成员方法:只能是抽象 方法----存在默认修饰符public abstract( 可以省略)
构造方法:接口没有构造方法
权限修饰符的范围
默认修饰符
私有修饰符private(权限最小)
受保护的protected
公共的public(权限最大)
1.类与类,类和接口,接口与接口的关系
Java中最基本的单元就是类,只支持单继承,
-
类与类:只支持单继承不支持多继承,但是支持多层继承
-
类与接口:是实现关系,一个类继承另一个类的同时,可以实现接口
-
接口与接口:不仅可以单继承,也可以多继承
2.接口与抽象类的区别
-
成员区别:
-
抽象类:
-
成员变量:可以是常量,也可以是变量
-
成员方法:可以是抽象方法,也可以是非抽象方法
-
构造方法:无参,有参都存在,子类继承父类,需要分层初始化
-
-
接口:
-
成员变量:只能是常量 public static final
-
成员方法:是抽象方法public abstract
-
构造方法:没有,需要借助子类进行实例化
-
-
-
关系区别:
-
类与类:可能是一些抽象类,继承关系,只支持单继承,不支持多继承,但可以多层继承
-
类与接口:实现关系implements;一个类继承另一个类的同时,还可以实现多个接口
-
接口与接口:继承关系 extends,支持单继承,可以多继承,多层继承
-
-
设计理念区别:
-
抽象类:不能实例化
-
需要通过具体的子类实现类(继承关系)
-
核心设计理念都是一种“is a”的关系(XX是XX的一种)
-
-
接口:不能实例化
-
需要通过具体的子类实现类实例化
-
核心设计理念是,事物的一种额外功能,看成一种“like a”的关系
-
-
3.形式参数问题,返回值问题--引用类型
形参如果是引用类型:
-
数组需要传递数组对象
-
具体类:实际参数需要传递该类的具体对象
-
抽象类:实际参数需要传递抽象类的子类对象(抽象类多态)
-
接口:实际参数需要传递接口的子实现类对象(接口多态)
返回值问题
返回值是引用类型:
具体类,需要返回当前类的对象 return new 类名();/类名 变量名=new 类名(); return 变量名;
抽象类:返回当前抽象类的子类对象(抽象类多态)
接口:返回接口的子实现类对象(接口多态)
equals判断时常量放前面,防止空指针NullPointException
instanceof:判断前面对象名是否是后面类型的一种实例 对象名 instanceof 对象名
4.包package的含义
本质就是文件夹,程序员在编写代码存储的地址
包在开发中,公司域名反写,多个包中间用"."隔开
包是为了维护代码结构需要代码分层
DAO:Data Access Object数据访问对象,数据访问层(持久层)
JDBC:连接数据库
service:业务访问层
commons/utils:存储一些通用工具类
controller:前后端交互(前后端中间层:连接层)
poji/domain/entity:存放Java实体类(满足JavaBean规范)
这个类是实体类
属性私有化
对外提供公共的set()/get()
api:接口文档工具
5.权限修饰符的默认修饰符private protected public
私有的private
受保护的protected
公共的public
权限 public > protected > private
-
在同一个包下同一个类中都可以访问
-
同一个包下的子类中private不能访问
-
同一个包下的无关类中private不能访问
-
不同包下的子类中,默认修饰符和private都不能访问
-
不同包下的无关类中,只有公共的可以用
6.内部类
一个类中有另一个类
内部类两种格式:成员内部类,局部内部类
内部类中访问的方式
成员内部类:
成员内部类可以访问外部类的成员,包括私有的方法/变量
直接通过外部类访问内部类的成员
外部类.内部类 对象名 = new 外部类().new 内部类();(适用于成员内部类是非静态)
外部类.内部类 对象名 = new 外部类. 内部类();(内部类是静态)
静态内部类中静态方法的调用:外部类.内部类.方法名
成员内部类的修饰符
可以有private修饰,目的是为了数据安全性
可以使用static,静态成员内部类只能访问外部类的静态成员
静态类的成员无论是静态方法还是非静态,只能访问外部类的静态成员
7.常用类
重要的几个类(牵扯类型转换):
Object
String
StringBuffer:线程安全的类
java.util.Date:日期类
String 日期文本--Date日期格式
基本类型四类八种--八个引用类型(Interger Character)
局部内部类
局部内部类可以直接访问外部类的成员,包括私有的
局部内部类访问,访问它的成员方法里面的局部变量,局部变量有什么特点?
jdk7及之前的版本,局部内部类访问局部变量的时候,局部变量必须使用final
局部变量随着方法的调用而存在,随着方法的调用的结束而消失,但现在通过局部对象调用他的方法
内部类的面试题
外部类和内部类没有继承关系
匿名内部类
没有名字的类
在局部位置定义
本质:就是继承该类(抽象类)或实现了该接口的子类对象
格式://相当new了一个对象
new 抽象类名/接口名(){
重写接口/抽象类的方法(){
}
};
调用多个方法时给匿名对象起一个名字
抽象类名/接口名 对象名=new 抽象类名/接口名(){
重写接口/抽象类的方法(){
}
};
降低耦合
选择排序
弊端:不稳定,时间复杂度较大O(n);
数组从角标0开始,依次和后面的元素比较,小的往前放,第一次结束,最小值就在最小索引处
常用类
java.lang.Object
所有类的父类,所有的类默认继承,有这个类的所有非私有方法
在Java中获取一个类的字节码文件对象的方式有几种?
1.public final Class getClass() 任意Java调用getClass
getClass获取一个类的字节码文件对象(返回值表示正在运行的那个类或者接口)
2.任意Java类型的class属性 类名.class
3.class类中有一个静态方法forName(“包名.类名”)
equals,toString建议子类必须重写
clone克隆