核心思想就是“隐藏细节”、“数据安全”:将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。也就是属性和方法的封装
典型案例:属性私有,提供getter setter方法
子类继承父类里面所有的属性和方法,构造方法除外使用关键字:extends
私有的属性和方法也可以被继承 ,但是不能被访问
(1)在多个不同的类中抽取出共性的数据和逻辑,对这些共性的内容进行封装一个新的类即父类(也叫做超类或基类),让之前的类来继承这个类,那些共性的内容在子类中就不必重复定义,比如 BaseDAO、BaseAction 等。
(2)Java 的继承机制是单继承,即一个类只能有一个直接父类。
(3)如果子类和父类有同名成员变量和方法,子类可以使用 super 关键字调用父类的成员变量和方法,上述使用方式前提是成员在子类可见。
(4)在调用子类构造方法时,会隐式的调用父类的构造方法 super()。如果父类没有无参构造方法,为了避免编译错误,需要在子类构造方法中显式的调用父类的含参构造方法。
(5)子类创建时调用父类构造方法:子类需要使用父类的成员变量和方法,所以就要调用父类构造方法来初始化,之后再进行子类成员变量和方法的初始化。因此,构造方法是无法覆盖的。
(6)当子类需要扩展父类的某个方法时,可以覆盖父类方法,但是子类方法访问权限必须大于或等于父类权限。
(7)继承提高了程序的复用性、扩展性,也是 Java 语言多态特征的前提。
(8)在实际开发、程序设计过程中,并非先有的父类,而是先有了子类中通用的数据和逻辑,然后再抽取封装出来的父类。
实例化过程
(1)JVM 读取指定 classpath 路径下的 class 文件,加载到内存,如果有直接父类,也会加载父类;
(2)堆内存分配空间;
(3)执行父类、子类静态代码块;
(4)对象属性进行默认初始化;
(5)调用构造方法;
(6)在构造方法中,先调用父类构造方法初始化父类数据;
(7)初始化父类数据后,显示初始化,执行子类的构造代码块;
(8)再进行子类构造方法的特定初始化;
(9)初始化完毕后,将地址赋值给引用
现实生活中的具体某个事物 转化成Java里面类的过程,只抽象与业务相关联的属性和方法例如:人(ID,姓名,年龄,电话,家庭住址 buy();eat();walk()?
一个事务的多种表现形式
编译时多态:看左边(父类)
运行时多态:看右边(子类)
Person p=new Person(); //普通创建对象(不是多态)
Person p=new Student(); //多态
Person p=new Teacher(); //多态
Shape shape=new Circle(); //多态
List list=new ArrayList(); //多态
静态变量就是被static关键字修饰的变量,在类被实例化时初始化,有且这有一份,被多个对象共享
成员变量是属于对象的变量,每个对象的成员变量不相同
final:最终的 终极的
属性或者变量:不可被修改 常量,命名:全部大写
方法:不可被重写
类:不可被继承
static:静态的
属性或者变量:属于类的,类加载的时候执行,共享的,有且只有一份,可以通过类名直接访问
方法:属于类的,类加载的时候执行,可以通过类名直接访问,一般工具类定义的时候使用
this:当前对象
this(参数列表):访问当前类的构造方法
this.属性:访问当前类的属性
this.方法:访问当前类的方法
super:父类对象
super(参数列表):访问父类的构造方法
super.属性:访问父类的属性
super.方法:访问父类的方法
构造方法:尽量不要去写功能业务代码(尽量写成方法调用)
格式: 修饰符 类名(参数列表){}
public Person(){ //无参数的构造器 -->手动添加
}
public Person(String name,int age,String address){ //有参参数的构造器
}
创建对象时候默认调用对应的构造方法
Person p=new Person(); //调用无参数的构造器
Person p=new Person(“张三”,22,“上海”); //调用有参数的构造器
作用:属性赋值
this.name=name;
this.age=age;
代码块就是{}花括号的内容
方法的签名:方法名+参数列表,代表方法的唯一
重写:本质,发生在父类与子类之间 ,扩展子类的业务功能
Object类是Java里面所有类的父类
重写Object类里面的三个主要方法:
toString(); //定义当前对象的打印规则
public String toString(){
return “User[”+username+","+age+","+address+"]";
}
equals(Object obj); //定义当前对象的比较规则
public boolean equals(Object obj){
if(obj==null) return false;
if(obj==this) return true;
if(obj instanceOf User){
User user=(User)obj;
return user.id==this.id; //ID是当前对象的唯一标识
}
return false;
}
hashCode(); //Java虚拟机(JVM)给每个对象分配一个散列码
public int hashCode(){
return this.id; //ID是当前对象的唯一标识
}
重载:本质,发生同一个类里面,方法名一样,参数不同(个数,顺序,类型) 代码的复用
Arrays.sort(int a);
Arrays.sort(long a);
Arrays.sort(double a);
1:相同点
a):都不能直接创建对象
b):普通类继承或实现抽象类与接口,都必须实现里面所有的抽象方法
2:不同点
a): 类的角度
abstract class shape:抽象类
interface UserDao:接口
b):属性的角度
抽象类,可以是普通变量也可以是常量
接口所有的属性都是常量,默认省略 public static final
c):方法的角度
抽象类:可以是普通的方法,也可以是抽象的方法
接口:所有的方法都是抽象方法 ,默认省略public abstract
d):获取实例的角度
抽象类,可以是普通方法
public shape getInstance{
return new shape(){};
}
接口:所有方法都是抽象方法,交给子类具体实现,不能够直接获取实例对象
抽象类:抽象的概念
图形类: abstract class shape:抽象类
圆,长方形等都是具体的了类,定义成具体的java、
接口:纯抽象的概念
java里面:一个类可以实现多个接口,可以是实现多个接口
类与抽象类是继承(extends)关系,类与接口之间是实现(implements)关系。
接口与接口之间是继承关系
public protected default private
public:公开的访问权限
protected:同一个包可以访问,子类里面也可以访问
default(默认修饰符):同一个包可以访问
private:私有的,同一个类里面可以访问
成员内部类:在类的代码块内定义的类,通常修饰符为defaul或private,变量的使用是就近原则,调用:Aoo aoo=new Aoo();
Boo boo=aoo.new Boo();
静态内部类:特殊的成员内部类,静态的内部类,可以直接被类名调用
Boo boo=new Aoo.Boo();
局部内部类:方法中的内部类,局部内部类调用外部变量,需要final修饰
匿名内部类:前提是存在一个类或者接口,这里的类可以是具体类也可以是抽象类。
本质是什么呢?是一个继承了该类或者实现了该接口的子类匿名对象。其实我个人感觉就是一个多态(向上转型),接着使用通过动态调用子类实现的方法。注意匿名内部类只针对重写一个方法时候使用匿名内部类是不能向下转型的,因为没有子类类名
==是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是地址值
equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,如果没有重写Object类中的equals方法,equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性
String:定长字符串
字符串池:对字符串进行优化操作
* 优化操作只针对于字面量的常量
* 字面量的常量:先去字符串池查找对象,如果没有直接传创建对象,
* 有的话直接重字符串池获取对象,不去创建新的对象。
String s1 = “abc”;
String s2 = “abc”;
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2));//true
String s1 = “abc”;//在常量池中
String s2 =new String(“abc”);//在堆内存中
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2));//true
byte b1=3;
byte b2=4;
byte b3=b1+b2;//这里是变量里面的值相加,jvm无法知道里面的值是多少,所以可能会溢出的安全问题,所以需要强制
byte b4=3+4;//jvm有常量优化机制,在编译时候就变成了7,接着把7赋值给b4
String s1=“a”+“b”+“c”;//jvm常量优化机制,类似byte b4=3+4;
String s2=“abc”;
System.out.println(s1 == s2); //true,常量优化机制
System.out.println(s1.equals(s2));//true
String s1=“ab”;
String s2=“abc”; //在常量池中
String s3= s1+“c”;//在堆内存中
System.out.println(s2 == s3); //false
System.out.println(s2.equals(s3));//true
A:String类重写了toString方法,返回的是该类对象本身
B: “”跟null区别:
“”是字符串常量,同时也是一个String类的对象,既然是对象,当然可以使用String类的方法
null是空常量,不能调用任何的方法(要不然报NullPointerException),null常量可以给任意的引用数据类型赋值
C:String.indexOf(a);获取指定值的索引值
D:String.SubString():字符串剪切
E:String.replace():字符串替换指定字符的第一个为另一个字符
F:String.replaceAll():字符串替换所有指定的字符为另一个字符
G:String.split():按照指定的字符切割成数组
StringBuffer:可变字符串
A:StringBuffer的添加功能
· .public StringBuffer append(String str):
可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
B:StringBuffer的删除功能
· .public StringBuffer deleteCharAt(int index):
删除指定位置的字符,并返回本身
· .public StringBuffer delete(int start,int end):
删除从指定位置开始指定位置结束的内容,并返回本身(删除的时候是包含 头,不包含尾) 注意:当缓冲区中这个索引上没有元素的时候就会报
· C:StringBuffer的替换功能
public StringBuffer replace(int start,int end,String str):
从start开始到end用str替换
D:StringBuffer的反转功能
public StringBuffer reverse():
字符串反转
E:StringBuffer的截取功能
·
注意事项
注意:返回值类型不再是StringBuffer本身
public String substring(int start):
从指定位置截取到末尾
public String substring(int start,int end):
截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
注意:
StringBuffer和StringBuilder的区别
StringBuffer是jdk1.0版本的,是线程安全的(安全就是同步的),效率低
StringBuilder是jdk1.5版本的,是线程不安全的(不安全就是不同步的),效率高
String,StringBuffer,StringBuilder的区别String是一个不可变的字符序列
StringBuffer,StringBuilder是可变的字符序列
Java中参数方法问题:
1.基本数据类型的值传递,不改变其值
2.引用数据类型的值传递,改变其值
3.String类虽然是引用数据类型,但是他当作参数传递时和基本数据类型是一样的,但StringBuffer,StringBuilder作为值传递,会改变其
A:Arrays类概述
.针对数组进行操作的工具类。
.提供了排序,查找等功能。
B:成员方法
.public static String toString(int[] a)//数组转字符串
.public static void sort(int[] a)//排序
.public static int binarySearch(int[] a,int key)//二分查找,找不到返回-插入点
A:为什么会有基本类型包装类
.将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。
B:常用操作
.常用的操作之一:用于基本数据类型与字符串之间的转换。
C:基本类型和包装类的对应
E:常用的包装类
.byte Byte
.short Short
.int Integer
.long Long
.float Float
.double Double
.char Character
-128到127是byte的取值范围,如果在这个取值范围内,自动装箱就不会新创建对象,而是从常量池中获取 * 如果超过了byte取值范围就会再新创建对象
正则表达式是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。
A:字符类
.[abc] a、b 或 c(简单类),其实[]代表单个字符
.[^abc] 任何的单个字符,除了 a、b 或 c(否定)
.[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
.[0-9] 0到9的字符都包括
B:预定义字符类
. 任何单个字符。
.\d 数字:[0-9]
.\w 单词字符:[a-zA-Z_0-9]
C:Greedy 数量词
.X? X,一次或一次也没有
.X* X,零次到多次
.X+ X,一次到多次
.X{n} X,恰好 n 次
.X{n,} X,至少 n 次
.X{n,m} X,至少 n 次,但是不超过 m 次
Date:日期类
calendar:日历类
SimperDateFormat:日期格式类
A:Date类的概述
.类 Date 表示特定的瞬间,精确到毫秒。
B:构造方法
.public Date()//如果没有传参数代表的是当前时间(从当前的系统获 得)
.public Date(long date)//如果构造方法中参数传为0代表的是1970年1月1日
C:成员方法
.public long getTime()//跟System.currentTimeMillis()一样
.public void setTime(long time)
D:SimpleDateFormat构造方法
public SimpleDateFormat()
.public SimpleDateFormat(String pattern)
//1,将生日字符串和今天字符串存在String类型的变量中
String birthday = “1983年07月08日”;
String today = “2088年6月6日”;
//2,定义日期格式化对象
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy年MM月dd日”);//如果上面用/,那么这里也要用/
//3,将日期字符串转换成日期对象
Date d1 = sdf.parse(birthday);
Date d2 = sdf.parse(today);
//4,通过日期对象后期时间毫秒值
long time = d2.getTime() - d1.getTime();//d2.getcurrent
//5,将两个时间毫秒值相减除以1000,再除以60,再除以60,再除以24得到天
System.out.println(time / 1000 / 60 / 60 / 24 );
JAVA异常机制:
自定义异常:1.java类继承Exception(常用),RuntimeException,Throwable(不常用)
2.手动添加父类的所有构造方法
JDk异常分类:
根:Throwable
--Error
--Exception(受检查异常)
--RuntionExcetion(非检查异常|运行时异常)
IllegalArgumentExeption 非法参数异常
NUllPointerException 空指针异常
ArrayIndexOutOfBoundsException数组下标越界异常
StringIndexOutOfBoundsException/字符串下标越界异常
ClassCastException 类型转换异常
NumberFromatException 数字格式转换异常
3关键字
try{}:可能发生异常的代码块放在try中
catch{}:异常捕获然后处理异常
finally :不管前面的代码是否发生异常,finally代码块一定会被执行,一般是资源的释放工作
throw:在业务里面抛出单个的异常对象
throws:声名多个抛出的异常对象
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。