目录
面向对象的思想
抽象数据类型的存储:
栈:存储方法,变量
堆:存储对象成员属性
原空间/方法区:对象的数据,类的信息,静态方法
JVM为每一个线程都创建了一个栈帧,JVM只有一个堆,方法区为所有线程共用,栈是在方法调用时开辟,存储局部变量,操作数,方法出口,是一段连续的内存,堆用来存储对象,数组,方法区用来存储程序中唯一不变的信息,类和字符串常量
public class CLASS {
public static void main(String[] args) {
User u1 =new User();
User u2=null;
}
}
class User{
}
u1初始化方式:栈-->原空间内有无类的信息
原空间-->堆内构建对象
堆内u1的地址-->赋值给u1
u2创建方法创建对象,堆内无对象
包
包就是对类进行分类管理,相同作用,相同类型的类一般放在一起去,可以包中包
在调用非Java.lang包下的东西的时候要进行,引用包,import+包名,引用一个包下的多个内容时可以使用通配符*:::::import Java.util.sql,Date / import Java.util.sql.*
类属性的初始化过程
默认初始化(只执行一次)
显示初始化(只执行一次)
构造器中的初始化(只执行一次)
调用对象属性,对象方法进行赋值
可变参数方法
可变参数语法规则即为:数据类型...变量名
void text(String...name)
可变参数与正常的参数放在一起时,可变参数要放在最后
void text(int age , String...name)
方法重载
即方法名相同,函数参数列表不同,构造函数也可以重载,
(idea里按下Alt+insert就可以偷个懒)
构造函数也可以调用构造函数的重载
class User{
int age;
String name;
public User(int age) {
this.age = age;
}
public User(int age, String name) {
this(11);//调用了第一个构造函数
this.name = name;
}
}
函数的参数类型必须不一样,调用哪个函数由提供的参数类型决定
方法重写
即方法名相同,函数参数列表也相同,用在继承里面
子类重写的返回值不能大于父类的返回值(student<person)
返回值为基本数据类型或void时必须相同
子类方法的访问权限不能小于父类方法的访问权限
父类的私有方法不能重写
子类抛出的异常不能大于父类抛出的异常
父类子类的方法必须同时不是static方法,static方法是类的方法,不能重写
object类
所有类的父类,里面有几个重要的方法
1:equals()判断相等
该方法底层就是==来判断是否相等,但是equals是可以重写的,对于String,File,Date和包装类都重写了object类的equals方法,用于比较两个实体对象的内容是否一样
2;toString()打印
直接print对象,其实就是调用toString方法,默认打印出来的是地址,可以通过重写来选择打印的内容,对于String,File,Date和包装类都重写了object类的toString方法,直接返回具体内容.
static关键字相关
成员方法可以调用静态方法和静态属性,静态方法不可以调用成员方法和成员属性;类的信息加载完成后可以调用静态代码块,可以完成静态属性的初始化,对象准备创建时也会调用代码块,但不是静态代码块,静态变量在JDK6之前存于方法区,从JDK7开始存于堆空间,静态方法不能用this,super调用.
单例模式
饿汉式;立即加载,随着类的加载,唯一的实例也加在了
//TODO 饿汉式 “立即加载”,随着类的加载,当前的唯一实例就创建了
class Bank{
//1. 类的构造器私有化
private Bank(){ }
//2. 在类的内部创建当前类的实例
private static Bank instance = new Bank(); //4. 此属性也必须声明为static的
//3. 使用getXxx()方法获取当前类的实例,必须声明为static的
public static Bank getInstance(){
return instance;
}
}
懒汉式:调用的时候进行创建
//TODO 懒汉式 "延迟加载",在需要使用的时候,进行创建。
class GirlFriend{
//1.类的构造器私有化
private GirlFriend(){ }
//2. 声明当前类的实例
private static GirlFriend instance = null; //4. 此属性也必须声明为static的
//3. 通过getXxx()获取当前类的实例,如果未创建对象,则在方法内部进行创建
public static GirlFriend getInstance(){
if(instance == null){
instance = new GirlFriend();
}
return instance;
}
}
单例模式后期可以用反射来打破
代码块
代码块只能用static来修饰
程序创建时调用::静态代码块-->代码块-->构造方法;静态代码块在类加载的时候执行,可以调用静态属性和静态方法非静态代码块在对象加载的时候执行,可以调用静态和非静态全部的属性和方法,所以代码块和静态代码块可以在对象赋值的时候使用,对象赋值的顺序::1默认初始化2显示初始化 3代码块的初始化4构造器初始化,至此初始化已经完成,后面初始化的值会覆盖前面初始化的值,在生成对象之后还可以通过对象.属性和对象.方法进行赋值,更改属性的值.
final
最终的意思
修饰类,为最终类,不可以有子类,修饰成员变量为常量,修饰方法表示方法不能重写
final修饰的成员变量可以在哪赋值:
1显式赋值
2代码块中赋值
3构造器中赋值
final修饰的局部变量,一旦赋值了就不能更改了,修饰方法内声明的局部变量,在调用之前一定要赋值,赋值后无法更改,修饰方法的形参:在调用此方法时一定要给形参赋值,赋值后无法更改
内部类
静态内部类和 非静态内部类
具体来说,当一个事物A的内部,还有一个部分需要一个完整的结构B进行描述,而这个内部的完整的结构B又只为外部事物A > 从类的角度看: - 内部可以声明属性、方法、构造器、代码块、内部类等结构 - 此内部类可以声明父类,可以实现接口 - 可以使用final修饰 - 可以使用abstract修饰 > 从外部类的成员的角度看: - 在内部可以调用外部类的结构。比如:属性、方法等 - 除了使用public、缺省权限修饰之外,还可以使用private、protected修饰 - 可以使用static修饰
静态内部类:可直接Person.Dog dog=new Person.Dog();
非静态内部类:要依靠外部类才能创建
Person p1=new Person();现有了P1
Person.Bird bird=p1.new Bird();再调用P1中的内部类Bird的构造方法
匿名对象 直接return,没有名字
匿名实现类 直接new,没有class
与接口一起用
//开发中的场景
public Comparable getInstance() {
//提供了实现了Comparable接口的类
//TODO 方式1:提供了接口的实现类的对象
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
return 0;
}
}
MyComparable m = new MyComparable();
return m;
//TODO 方式2:提供了接口的实现类的匿名对象
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
return 0;
}
}
return new MyComparable();
// TODO 方式3:提供了接口的匿名实现类的对象
Comparable c = new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
// return c;
//TODO 方式4:提供了接口的匿名实现类的匿名对象
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
枚举类型
enum city{beijing,shanghai,hangzhou,......}
不会创建对象
JDK5之前的枚举类/手写枚举类
class Season{
//TODO 1. 声明当前类的对象的实例变量,使用private final修饰
private final String seasonName;//季节的名称
private final String seasonDesc;//季节的描述
//TODO 2. 私有化类的构造器
private Season(String seasonName,String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//TODO 3. 提供实例变量的get方法
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//TODO 4. 创建当前类的实例,需要使用public static final修饰
public static final Season SPRING = new Season("春天","春暖花开");
public static final Season SUMMER = new Season("夏天","夏日炎炎");
public static final Season AUTUMN = new Season("秋天","秋高气爽");
public static final Season WINTER = new Season("冬天","白雪皑皑");
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
注解
常用注解
`@Override`: 限定重写父类方法,该注解只能用于方法 `@Deprecated`: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择 `@SuppressWarnings`: 抑制编译器警告
用户自定义注解:
要用元注解,元注解即修饰注解的注解,对现有的注解进行修饰
(1)@Target:用于描述注解的使用范围 可以通过枚举类型ElementType的10个常量对象来指定 TYPE,METHOD,CONSTRUCTOR,PACKAGE..... (2)@Retention:用于描述注解的生命周期 可以通过枚举类型RetentionPolicy的3个常量对象来指定 SOURCE(源代码)、CLASS(字节码)、RUNTIME(运行时) 唯有RUNTIME阶段才能被反射读取到。 (3)@Documented:表明这个注解应该被 javadoc工具记录。 (4)@Inherited:允许子类继承父类中的注解
@Target({TYPE, FIELD, METHOD,CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "hello";
}
包装类
为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各个基本数据类型的变量都提供了对应的包装类。 基本数据类型对应的包装类类型 byte -> Byte short -> Short int -> Integer long -> Long float -> Float double ->Double char -> Character boolean -> Boolean
(装箱)基本数据类型 ---> 包装类:
① 使用包装类的构造器
② (建议)调用包装类的valueOf(xxx xx)
③ 自动装箱
Integer ii1 = new Integer(10);不推荐使用
Integer ii2 = Integer.valueOf(10);
Integer ii2 = 10
(拆箱)包装类 ---> 基本数据类型:
① 调用包装类的xxxValue() ② 自动拆箱
int i1=ii1.intValue();
int i2 = ii1;
基本数据类型,String,包装类之间的转换:
封装
有四种权限
public权限,可以被任何类访问
protected权限 本类,本包其他类,其他包的子类继承
默认权限 本类,本包其他类
private权限 该类自己
JavaBean:类的成员属性均为private,提供get和set方法
继承
extend,Java只支持单继承一个类只能有一个父类(interface可以弥补单继承的局限性)
继承时可利用super和this来调用父类子类的同名方法,
多态
父类的引用指向子类的对象
比如:Person p2 = new Man();
多态的应用:编译时看左边,运行时看右边;即编译时,认为方法是左边声明的父类的类型的方法(即被重写的方法),执行时实际执行的是子类重写父类的方法.
多态的前提:1要有继承2要有重写
方法调用:一个对象能够使用什么取决于引用变量的类型
一个对象具体使用什么是看具体对象
一个对象的属性具体的使用是不需要看具体的对象的,属性在哪里声明就在哪里使用
抽象
abstract关键字
修饰类
此类为抽象类,抽象类不能实例化,抽象类包含了构造器因为子类对象实例化的时候需要直接或者间接的调用父类的构造器;抽象类可以没有抽象方法,但是由抽象方法的类一定是抽象类
修饰方法
此方法为抽象方法,抽象方法只有方法的声明没有方法体,抽象方法的功能是确定的,(通过方法的声明即可确定),只是不知道具体该怎么实现(体现为没有方法体),子类必须重写父类的所有抽象方法之后才可以实例化,要不然子类仍然是一个抽象类.