构造方法
1)方法名和类名一致
2)没有具体返回类型(无void)
格式
public 方法名和类名一致{空参/传参}
无参构造
有参构造
注意事项
** 1)一个类中如果没有提供任何构造方法,系统会默认提供一个无参构造方法
2)如果一个类中提供了有参构造方法,系统不会无参构造方法,如果你还要使用无参构造方法来创建类对象,报错!**
类名 对象名 = new 类名() ; 默认执行的无参构造方法
举例说明
class Student{
//无参构造方法
public Student(){
System.out.println("这是Student的无参构造方法");
}
//有参构造方法:带上参数类型以及参数名
public Student(String name){
System.out.println(name);
System.out.println("这是带一个参数的有参构造方法");
}
public Student(String name,int age){
System.out.println(name+"---"+age);
System.out.println("这是带两个参数的有参构造方法");
}
}
一个类中的成员
成员变量
class Demo{
int a ;
int b ;
public int add(){
return a + b ;
}
public int add(int a,int b){
return a +b;
}
}
变量的定义的时候:如果能够描述这个事物的属性—定义成员变量
长方形----长和宽:就是它的属性
关于变量的使用问题:(细节)
-
什么是将变量定义为成员变量?
-
如果这个需求能够描述现实世界事物的属性,这个时候才能将变量定义成员变量,全部都是局部变量!
-
因为局部变量它的生命周期:随着方法调用存在,随着方法调用结束而消失
给成员变量赋值的两种方式
1)setXXX(xx)赋值
2)有参构造方法赋值
static关键字
static关键字的特点
1)随着类的加载而加载
类在在加载的时候,静态相关的成员(类成员:静态的变量或者静态的方法),随着类的加载而先进内存(静态区)
== 2)优先于对象存在, 不能和this共存==
== 3)static能体现"共享,共用"的意思==
如果需求中有"共用"含义,这个变量直接使用static修饰
== 4)被static修饰的成员(变量/方法),推荐的访问方式是使用类名.静态变量==
类名.静态方法名()
可以使用_类名 对象名 = new 类名() ;_
对象名.静态变量() (不推荐)
对象名.静态方法() (不推荐)
在使用静态相关变量/方法,他们的注意事项:
1)非静态的方法,既可以静态的,也可以访问非静态的(要么访问静态变量/静态的方法)
2) 简单记忆:
静态只能访问静态的东西(静态变量/调用静态方法)
数组工具
针对数组的操作的工具类,会提供针对数组各种各样的操作
工具类中,构造方法私有化,对外提供静态的公共的方法! (后面设计模式:工厂设计模式(创建型))
public class ArrayTool {
如果将这个类的无参构造方法私有化了
工具类中:构造方法都是私有,不让外界去创建当前类对象
private ArrayTool(){}
加入static
public int getMax(int[] arr){
这个方式是获取数组中最大值
@param arr 在指定数组中进行操作
@return 最终返回数组中最大值
代码块
Java中的代码块 {}分类
局部代码块:比较简单,在局部位置(方法定义中)定义的{},作用:限定某个变量的生命周期(很少见)
构造代码块:在类的成员位置 ,作用:
在执行构造方法之前,如果存在构造代码块,优先执行构造块,然后执行构造方法
可以将构造方法中共性内容,放在构造代码块中!(优先级:构造代码块>构造方法)
静态代码块 (实际开发中用的比较多:后期 二阶段:读取jdbc配置文件/加载某个框架的核心配置文件)
static{},在类的成员位置 ,类一加载,静态代码块先执行!
类就加载一次,静态代码块也就执行一次就完毕
一个类中如果有静态代码块,有构造代码块,有构造方法
== 静态代码块 > 构造代码块 > 构造方法==
继承(extends)
将多个事物(类)的共性内容抽取到一个独立的事物(类)中,
-
这个事物(类)和其他事物(其他类)之前产生一种关系,称为"继承" 关键字 “extends”
格式:
class 父类名{
共性内容:属性私有化
对外提供公共的访问方法
其他成员方法
}
class 子类名 extends 父类名{}
从下面代码看,继承的特点:
1)提高了代码的复用性
2)提高了代码的维护性(方便后期维护)
3)类与类产生的继承关系,是多态的前提条件!弊端:
继承的关系:是存在局限性,不要为了使用部分功能而去使用继承!
什么时候使用继承?
如果一个类A是类B的一种,或者B类是A类的一种,这个时候使用"继承"
体现的一种"is a"的关系
水果
苹果
香蕉
橘子…class A{
public void show(){}
public void show2(){}
}
class B{ //class B extends A{}
public void show2(){}
public void show3(){}
}
所有开发原则(接口分离/迪米特/开闭原则/依赖倒置…)都必须遵循: “低耦合,高内聚”(核心原则)
耦合:就是类和类的关系,越少越好 (耦合度只能降低,不能去避免!)
内聚: 某一个类完成某件事情能力!(一个类能完成,尽量一个类去完成!)
继承的好处及注意事项
继承的好处:
1)类和类之间的关系,只支持"单继承"
class Fu{}
class GrandFu{}
class Zi extends Fu,GrandFu{}//错误的! (多继承,Java没有多继承的概念)
2)不支持多继承,但是可以 “多层继承”
== 继承中的注意事项:==
1)子类继承父类,只能继承父类的非私有的成员,私有的成员,可以间接的访问
2) 子类继承父类,构造方法是不能继承的,只能间接访问!
继承成员变量访问问题
继承中关于成员变量的问题
1)如果子类继承父类,子类的成员变量名称和父类的成员变量不一致,分别访问即可(比较简单一些)
2)如果子类中的成员变量名称和父类的成员变量一致,如何访问呢?
就近原则机制
1)首先先在子类的局部位置(成员方法)找,如果有,就使 2)如果子类的局部位置没有,那么就在子类的成员位置中找,有就使用
3)如果子类的成员位置也没有,那么就在父类的成员位置中找,有就使用,
4)如果父类也没有,继续往他的父类上找,最终顶层父类中都没有,那么报错(找不到这个变量!)
继承的构造方法访问问题:super访问
this:代表当前类对象的地址值引用
super:代表父类的空间标识(理解为:父类对象地址值引用)
this.变量名:访问的本类的成员变量
super.变量名:访问的父类的成员变量
继承的成员方法访问问题
构造方法目的:就是类的成员进行数据初始化!
- 继承关系中,子类不能继承父类的构造方法,但是可以间接通过super()来访问,为什么子类中构造方法默认是这种机制呢?
- 子类的所有构造方法都默认访问父类的无参构造方法(子类的所有构造方法的第一句话super();,可以省略不写), 因为:jvm 校验语法的时候, class Zi extends Fu{}存在继承关系,需要让父类先初始化,因为子类可能会用父类的数据,所以采用"分层初始化!"
问题
继承关系中, 父类的中如果没有无参构造方法(存在有参构造方法),子类会出现什么情况?如何解决呢?
答
子类全部报错,子类的所有构造方法都默认访问父类的无参构造方法(子类的所有构造方法的第一句话super();,可以省略不写)
1)解决方案1:永远给出类的无参构造方法
2)如果现在不给出父类无参构造方法,如何解决呢?
让子类的所有构造方法显示的访问父类的有参构造方法!(只要父类出现初始化 :执行构造方法就是初始化)
3)子类的所有构造方法中的某一个只要能够让父类初始化即可!
创建Zi zi = new Zi() ; 在执行Zi类的无参构造方法的时候
让它先执行子类的有参构造方法 this(xx) ;
让后在子的有参构造方法中,让它先让父类初始化 super(xx) ; 访问父类的有参构造方法
使用继承关系 编码的时候:----idea生成 alt+ins---->constructor—>
子类的无参构造方法 访问父类的无参构造方法
子类的有参构造方法 直接访问父类的有参构造方法
多态
多态的概念:
从现实世界事物中考虑 :“多态” 一个事物多种形态!
水
固态,气态,液态
Java面向对象中(程序中)“多态”: 一个类体现出内存的变化
猫类 Cat Cat c = new Cat() ;
Animal a = new Cat() ; //猫是动物 (继承关系)
多态:能够体现事物的不同形态(程序中,内存的变化!)
多态的前提条件:
== 1)必须有继承关系 (如果没有继承,不谈多态)
2)必须存在方法重写
猫和狗都需要吃饭,吃的东西不一样(具体的动物类中应该给出具体体现)
3) 必须存在父类引用指向子类对象==
** 格式:
父类名 对象名 = new 子类名() ; (向上转型!)
父类名 对象名 = new 子类名() ;**
多态的好处及弊端
多态的好处:
1)可以提高代码的扩展性 (父类引用指向子类对象 Fu fu = new Zi()) 多态保证的 (重点)
2)可以提高代码的复用性以及维护性(由继承保证的)
多态的弊端:
父类引用指向子类对象, 父类名 对象名 = new 子类名() ;(向上转型)这种格式无法访问子类的特有功能
解决方案:
1)直接创建子类对象 子类名 对象名 = new 子类名() ;
虽然可以,但是new 子类名() ;需要开辟堆内存空间(消耗内存空间) (内存角度考虑不太好)
2) 推荐:向下转型
将父类引用强转为子类引用!-----就是我们 基础"强转类型转换" (将大类型—小类型)
int num = 65 ;
char c = (char)num ; // ‘A’
== 父类名 父类的引用 = new 子类名() ; 向上转型==
== Fu f = new Zi() ;==
== 子类名 对象名 = (子类名)父类的引用; 向下转型 --前提必须有向上转型==
== Zi z = (Zi)f;==
可能出现的问题
- 多态的向下转型(将父类引用强转子类引用),使用不当,会存在一个问题
- java.lang.ClassException:(属于运行时期异常的一种)类转换异常:一般都出现在多态向下转型使用不当就会出现这个问题
- 最终的结果类型和堆内存中存储的实例类型不一致!
- 解决方案:检查下的代码逻辑(需要什么类型,里面存储的什么类型!)
多态的成员特点
多态的成员访问特点:
** 1)成员变量:编译看左,运行看左!**
** _ 2)成员方法:编译看左,运行看右 !(非静态的成员方法)**
** 静态的方法:算不上方法重写,跟类相关,类一加载就可以直接使用(类名.方法名())**
** _ 3)构造方法:由于存在继承,构造方法在执行的时候,分层初始化,先让父类初始化,然后再是子类进行构造初始化!**
abstract关键字(抽象)
什么是抽象类?
一个事物的某个行为应该具体的事物的具体体现,将这个事物顶层次(父类)可以定义"抽象"
举例
动物事物—都具备吃和睡的行为
只有见到具体的事物才具备的具体行为 “猫”,"狗"吃和睡不一样,应该在具体事物中给出具体的体系,那么在
动物事物中,仅仅一个声明!(没有方法体)
抽象类的定义:
abstract class 类名{}
有抽象方法的类一定是抽象类, 抽象类不一定都是抽象方法 (重点)==
抽象方法的格式:
权限修饰符 abstract 返回值类型 方法名(空参/无参);
抽象类的特点:
1)抽象类不能进行实例化! (不能 创建对象)
2)抽象类的子类如果也是抽象类,不能实例化,一定会提供最具体的子类 完成实例化(创建对象)
抽象的父类名 对象名 = new 具体的子类名() ; 抽象类多态
抽象类成员特点
抽象类的成员特点:
成员变量:
既可以是变量,也可以是常量!(加入final修饰)
成员方法:
皆可以存在抽象方法(不能省略abstract关键字,必须强转子类重写),也可以定义非抽象方法
构造方法:
无参构造/有参构造都可以存在, 构造方法都需要让父类先初始化,然后再是子类进行初始化!
抽象类问题
如果一个类没有任何抽象方法,把这个类定义为抽象类的意义?
意义就是:不让外界类直接创建对象(抽象类不能创建对象)----需要提供具体的子类进行实例化!
abstract和哪些关键字冲突?
不能private一块用:被private修饰的成员需要在当前类进行访问,而如果加入abstract,强制子类完成…
不能和final一块用: 被final修饰的成员方法,不能被重写!而abstract抽象方法,必须强制子类重写
不能和static一块用:被static修饰的成员方法,算不上重写…
abstract关键字应用范围:
1)定义类—抽象类
2)定义方法—>抽象方法
接口
什么是接口?
接口 体现的是这个事物本身不具备的功能,额外的功能;
举例:
猫和狗 ----> 开始不具备 “跳高”,“钻火圈”
—>驯养师---->训练猫和狗---->后天具备 “跳高”,“钻火圈”
中国人---->经过后天学习 “英语口语” ----> 具备说"英语口语"的行为!
接口定义—Java代码定义 关键字 interface 接口名{}
接口名标识符---->和类名起名字一致"大驼峰命名法"
接口的特点:
1)接口的方法不能有方法体,只能是抽象方法 而且隐藏public abstract(可以省略不写)
2)接口不能实例化(不能创建对象)
3)如果接口的实现类它是一个抽象类(不能实例化),肯定有一个具体的接口的实现类来进行new对象
接口名 对象名 = new 具体的子实现类() ; 接口多态
要实现接口里面的额外功能---->才具备这功能
开发中定义接口的实现类(子类)名
class 接口名+Impl implements(实现) 接口名{}
接口成员特点
接口的成员特点:
成员变量: 只能是常量— 存在默认修饰符 public static final (可以省略)
成员方法: 只能是抽象方法----存在默认修饰符 public abstract(可以省略)
构造方法: 接口没有构造方法!
权限修饰符的范围
默认修饰
private
protected
public
同一个包下
同一个包同一个类中都能访问
同一个包中的子类中private无法访问
同一个包下的无关类private同样无法访问
不同包下
在不同包下的子类中默认修饰符和private都无法访问
无关类中默认修饰符 private protected 都无法访问
总结
私有修饰符权限最小,public权限最大,默认修饰符需要在同一个包中,protected在源码中会见到
形式参数问题/返回值问题(引用类型)
方法的返回值问题:
- 1)返回基本类型: 需要什么基本数据类型,使用对应性的类型接收
- 2)研究引用类型:
类
具体类: 需要返回的是当前具体类的对象 !
抽象类: 需要返回的是当前抽象类的子类对象(抽象类多态)
接口 :需要返回的是接口的子实现类对象(接口多态)
关于类与类,类与接口,接口与接口的关系
类与类:继承关系,单继承,可以多层继承。
类与接口:实现关系,非抽象类实现接口时,必须将接口中的方法实现。抽象类实现接口时,可以实现也可以不实现方法。
接口与接口:继承关系,一个接口可以继承多个接口。
包package的含义
package包—本质就是文件夹(目录)
程序员在编写代码存储的地址
包---->开发中 (公司域名反写,多个包中间.隔开)
公司域名
com.qf
本质
com文件夹
qf文件夹
xx.java
包----为了维护代码结构的(代码分层)
com.qf.pojo/domain/entity: 存放Java实体类(满足JavaBean规范:)
1)这个类是具体类
2)属性私有化 (属性必须全部字母小写)
3)对外提供公共的setXXX(xx)/getXXX()
带包的运行和编译
带包的编译和运行:如果使用记事本方式,自己手动编译
两种方式
1)手动方式(不推荐)
a)先将包的结构创建好
b)进入dos,进入到指定xx.java文件目录中,先使用javac java源文件—>类名.class
c)将b)产生的类名.class放在包的结构下面
d)直接java 包名.类名 运行即可!
2)自动方式(推荐)
如果使用另一个包下的类,进行导包之后和下面操作一样
a) 进入dos,进入到xx.java文件的目录
b)javac -d . java源文件---->会自动将package 包的结构创建出来将类名.class放进去
c)直接java 包名.类名 运行即可!
内部类(了解)
//内部类----实际开发中(应用层面居多)
//内部类里面的一些访问方式(重点)
//属于设计层面(jdk源码里面会看到)
class Outer{
//成员内部类
class Inner{
}
}
class Outer{
public void show(){
//局部位置
class Inner{} //局部内部类
}
}
常用类
重要的几个类(凡是 类型转换都是重点)
Object
String (里面功能最多
转换
截取
替换
字典比较
)
StringBuffer(线程安全的类)
java.util.Date:日期类
String日期文本---->Date日期格式
基本类型四类八种---->八个引用类型(Inetger,Character)
BigDecimal:小数精确计算
System