一 面向对象上一
1 对三大特性的理解
1.1 封装性
指一个类把自己内部的实现细节进行隐藏,只暴露对外的接口(setter和getter方法)。
封装又分为属性的封装和方法的封装。把属性定义为私有的,它们通过setter和getter方法来对属性的值进行设定和获取。
总体上体现为四种权限修饰
1.2 继承性
指在一个现有类(父类)的基础上在构建一个新类(子类),子类可以拥有父类的成员变量以及成员方法(但是不一定能访问或调用,例如父类中private私有的成员变量以及方法不能访问和调用)。
继承的作用就是能提高代码的复用性。子类拥有父类中的一切(拥有不一定能使用),它可以访问和使用父类中的非私有成员变量,以及重写父类中的非私有成员方法。
继承的好处是实现代码的复用以及扩展,子类通过对父类代码的复用,可以不用再定义父类中已经定义的成员变量,方法上直接对父类的方法进行重写实现了扩展。
1.3 多态性
多态就是指多种状态,就是说当一个操作在不同的对象时,会产生不同的结果。(给对象一个激励,让对象自行决定应该做出何种响应。)
在Java中,实现多态的方式有两种,一种是编译时的多态,另外一种是运行时多态,编译时的多态是通过方法的重载实现的,而运行时多态是通过方法的重写实现的。
方法的重载是指在同一个类中,有多个方法名相同的方法,但是这些方法有着不同的参数列表,在编译期我们就可以确定到底调用哪个方法。
方法的重写,子类重写父类中的方法(包括接口的实现),父类的引用不仅可以指向父类的对象,而且还可以指向子类的对象。当父类的引用指向子类的引用时,只有在运行时才能确定调用哪个方法。
其实在运行时的多态的实现,需要满足三个条件:1.继承(包括接口的实现)2.方法的重写 3.父类的引用指向子类对象
并且,我们说的多态都是类中方法的多态,属性是没有多态性的。
-
实现代码的通用性
-
Object类中定义的public boolean equals(Object obj){}
JDBC:使用java程序操作(获取数据库连接、CRUD)数据库
-
抽象类、接口的使用肯定体现了多态性(抽象类、接口不能实例化)
-
多态是运行时行为,取随机数证明,编译时看不出,运行时才看得出
2 static关键字
static:静态的
static可以用来修饰:属性、方法、代码块、内部类
2.1 使用static修饰属性:静态变量
属性按是否使用static修饰,又分为:静态变量(类变量) VS 非静态属性(实例变量)
实例变量:当创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会对其他对象同样的属性值产生改变
静态变量:当创建了类的多个对象,多个对象共享同一个静态变量。当通过一个对象修改静态变量时,会导致其他对象调用此静态变量时,是被修改过的。
2.1.1 其他说明
-
静态变量随着类的加载而加载,可以通过**“类名.静态变量”/“对象名.静态变量”**的方式进行调用
-
-
静态变量的加载早于对象的创建
-
由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区的静态域中
2.1.2 举例
System.out
Math.PI
2.1.3 内存结构
2.2 使用static修饰方法:静态方法
2.2.1 说明
-
静态方法随着类的加载而加载,可以通过**“类名.静态方法”/“对象名.静态方法”**的方式进行调用
-
-
静态方法中,只能调用静态的属性或方法
非静态方法中,既可以调用非静态的属性或方法,也可以调用静态的属性或方法
(从生命周期考虑)
2.3 static注意点
- 在静态的方法中,不能使用this关键字,super关键字
- 关于静态属性和静态方法的使用,从生命周期的角度去理解
2.4 总结
2.4.1 在开发中,如何确定一个属性是否要声明为static?
- 属性是可以被多个对象共享的,不会随着对象的不同而不同的
2.4.2 在开发中,如何确定一个方法是否要声明为static?
- 操作静态属性的方法,通常设置为static的
- 工具类中的方法,习惯上声明为static的。比如:Math、Arrays、Collections…
2.5 代码实例
public class CircleTest{
public static void main(Stinr[] args){
Circle c1 = new Circle();
Circle c2 = new Circle();
System.out.println(c1.getId());//1001
System.out.println(c2.getId());//1002
System.out.println(Circle.getTotal());//2
}
}
class Circle{
private double radius;
private int id;
public Circle(){
id = init++;
total++;
}
public Circle(double radius){
this();
this.radius = radius;
//id = init++;
//total++;
}
private static int total;
private static int init = 1001;//属性被所有对象共享
public double findArea(){
return 3.14 * radius * radius;
}
//get和set方法
}
3 单例(Singleton)设计模式
- 设计模式**是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。**设计模式免去外面总结再思考和摸索。式就像是经典的棋谱,不同的器具,外面用不同的棋谱,“套路”
- 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果外面要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能有new操作符再类的外部产生类的对象了,但是在类的内部可以产该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对称,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的
3.1 代码实现
3.1.1 饿汉式
public class SingletonTest1{
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
bank1 = bank2;//true
}
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此对象也必须声明为静态的
private static Bank instance = new Bank();
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
3.1.2 懒汉式
public class SingletonTest1{
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
bank1 = bank2;//true
}
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.声明当前类对象,没有初始化
//4.要求此对象也必须声明为静态的
private static Bank instance = null;
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
if(instance == null){
instance = new Bank();
}
return instance;
}
}
3.1.3 两者优缺点
- 饿汉式
- 坏处:对象加载时间过长
- 好处:线程安全
- 懒汉式
- 好处:延迟对象的创建
- 坏处:线程不安全
3.2 举例
3.3 应用情景
4 理解main方法的语句
public class MainTest{
public static void main(String[] args){
}
}
main也可以通过控制台传入数据,运行时传入 (String[] args)
5 类的成员之四:代码块(Block)
开发中好鸡肋的东西…
public class BlockTest{
public static void main(String[] args){
String desc = Person.desc;//Hi,static block
Person p1 = new Person();//Hi,block
Person p2 = new Person();//Hi,block
}
}
public class Person{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//代码块
//静态代码块
static{
System.out.println("Hi,static block1");
}
static{
System.out.println("Hi,static block2");
}
//非静态代码块
{
System.out.println("Hi,block");
}
//方法
public void eat(){
}
public void sleep(){
}
//toString重写
public String toSting(){
}
}
5.1 作用
用来初始化类、对象
5.2 注意
代码块如果有修饰,只能使用static
5.3 分类
开发中没有必要造多个代码块
5.3.1 静态代码块
- 内部可以有输出语句
- 随着类的加载而执行,而且只执行一次
- 作用:初始化类的属性等
- 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
- 静态代码块的执行优先非静态代码块的执行
5.3.2 非静态代码块
- 内部可以有输出语句
- 随着对象的创建而执行
- 每创建一个对象,就执行一次
- 作用:初始化对象的属性等
- 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
5.4 继承情况初始化顺序实例
class Parent {
/* 静态变量 */
public static String p_StaticField = "父类--静态变量";
/* 变量 */
public String p_Field = "父类--变量";
protected int i = 9;
protected int j = 0;
/* 静态初始化块 */
static {
System.out.println( p_StaticField );
System.out.println( "父类--静态初始化块" );
}
/* 初始化块 */
{
System.out.println( p_Field );
System.out.println( "父类--初始化块" );
}
/* 构造器 */
public Parent()
{
System.out.println( "父类--构造器" );
System.out.println( "i=" + i + ", j=" + j );
j = 20;
}
}
public class SubClass extends Parent {
/* 静态变量 */
public static String s_StaticField = "子类--静态变量";
/* 变量 */
public String s_Field = "子类--变量";
/* 静态初始化块 */
static {
System.out.println( s_StaticField );
System.out.println( "子类--静态初始化块" );
}
/* 初始化块 */
{
System.out.println( s_Field );
System.out.println( "子类--初始化块" );
}
/* 构造器 */
public SubClass()
{
System.out.println( "子类--构造器" );
System.out.println( "i=" + i + ",j=" + j );
}
/* 程序入口 */
public static void main( String[] args )
{
System.out.println( "子类main方法" );
new SubClass();
}
}
初始化顺序:
父类–静态变量/父类–静态初始化块
子类–静态变量/子类–静态初始化块 + 子类main方法
父类–变量/父类–初始化块
父类–构造器
子类–变量/子类–初始化块
子类–构造器
总结:由父及子,静态先行
5.5 初始化顺序:
-
默认初始化 -->
-
显式初始化 / 代码块初始化 (关注谁先写谁后写) -->
-
构造器初始化 -->
-
有了对象后,通过“对象.属性” “对象.方法”进行赋值
6 final关键字
final:最最终的
final可以用来修饰:类、方法、变量
6.1 使用final修饰类
final class FinalA{
}
final用来修饰一个类:此类不能被继承,无子类(太监类)
比如:String类、System类、StringBuffer类
6.2 使用final修饰方法
final用来修饰一个方法:此方法不能被重写
比如:Object类中的getClass()
6.3 使用final修饰变量
final用来修饰一个变量:此时的“变量”就称为一个常量
6.3.1 final修饰属性
可以考虑赋值的位置有:显式初始化、代码块初始化、构造器初始化
6.3.2 final修饰局部变量
public void show(){
final int NUM = 10;
}
public void show(final int NUM){
system.out.println(NUM);
}
尤其是final修饰形参时,表明此形参是一个常量
当我们调用此方法时,给常量形参赋一个实参。
一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值
6.4 static final
修饰属性、方法
6.4.1 修饰属性
static final 全局常量(表示属性不能改变)
修饰方法少见