标签:
- 在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的 联系,这种思想就是面向对象。
- 在现实生活中存在的具体的一个事物。
- 实际就是对某种类型事物的公共属性与行为的抽取。(类是一个抽象的概念,就相当 于图纸)
- 类时对象的模板 - 汽车图纸
- 对象是类的实例 - 各种汽车
- 找适合的对象做适合的事。
- 1. 封装
- 2. 继承
- 3. 多态
- 方式一 : sun 给我们定义好了很多的类,我们只需要认识这些类即可创建对象为我 们使用。
- 方式二 : 我们要自定义类, 然后通过自定义的类创建对象为我们服务。
格式:
class 类名 {
事物公共的属性使用成员变量描述;
事物的公共行为使用函数描述;
}
格式:
类名 变量名 = new 类名();
1. 成员变量(访问对象的属性)
对象.属性名;
2. 成员方法(调用对象的功能)
对象.函数名();
* 注意:成员位置只能用于定义函数或者是定义一个变量,不能写任何的执行语句
- 1. 成员变量在整个类内都有效
- 2.局部变量只在其声明的方法内有效
- 1. 成员变量:它属于对象,它随着对象的创建而创建,随着对象的消失而消失
- 2.局部变量:使用完马上释放空间
- 1.成员变量属于对象,它存储在堆内,堆内的实体,当没有引用指向其时,才垃 圾回收清理
- 2.局部变量存在栈内存中,当不在使用时,马上就会被释放
- 1.成员变量它存储在堆中,如果没有赋初值,它有默认值
- 1. 整数byte、short、int、long = 0 ;
- 2. char = ‘\uoooo’;
- 3. boolean = false;
- 4. String = null;
- 5. 类类型 = null;
- 6. 数组 = null;
- 2. 局部变量,如果要想使用必须手动初始化
- 1. 方法中,参数列表中,语句中
- 2. 必须给初始化值,没有初始值,不能使用
- 3. 在栈内存中
- 1. 如果需要调用一个对象的功能一次的时候,然后该对象就不再使用了,这时候可 以使用匿名对象。(为什么只调用方法,而不调用属性呢?因为匿名对象调用属性 没意义。如果对象要对成员进行多次调用,必须给对象起个名字。不能使用匿名对 象。)
- 2. 可以作为参数传递调用方法。
- new Car().run();
- 简化书写
- 1. 一般都不要给匿名对象赋予属性值,因为永远都没法获取到。
- 2. 两个匿名对象永远都不可能是同一个对象。
- 1:new Car().num = 5;
- 2:new Car().color = “blue”;
* 注意:两个new是两个不同的对象,在堆内存中有不同的空间,相互不干扰。
- 隐藏对象的属性与具体的实现细节, 对外提供公共的访问方式。
- 1. 出现了数据安全问题
- 2. 根本原因:别人可以对对象的属性进行直接的赋值,赋值之前没有经过任何的判 断。
- 访问权限修饰符也就是控制类、属性、 方法的可见范围的。
- private: 私有的,如果使用了private修饰的函数或者是属性(成员变量),那么被修 饰的成员只能在本类中可见。
- public :公共的,任何人都可以进行访问。
- 1. 使用private修饰需要被封装的属性,把属性给隐藏起来。(使用private修饰成员 变量)
- 2. 对外提供公共的访问方式。(设置、获取)
- 命名规范:
set属性名
get属性名
- 疑问1: 封装都需要提供get与set方法才称作为封装吗?
不一定,看需求而定。
- 疑问2: 对外提供的设置以及获取属性的方法名一定要叫get、set吗?
不一定,只不过是一个命名规范。
* 在现实开发中的规范: 一般实体类的所有成员变量都会封装起来。
* 类:
- 工具类 : Arrays(数组的工具类), 主要是提供一个方法对外进行访问,方便用户 操作数据。
- 实体类: 描述一类事物的公共属性与公共行为的, 比如: 人类、 汽车类...
- 1. 提高了数据的安全性。
- 2. 提高代码的复用性。
- 3. 隐藏了具体的实现, 操作简单了。
- 构造函数的作用是初始化对应的对象。
修饰符 函数名(形式参数列表){
初始化对象的语句;
}
- 1. 构造函数是没有返回值类型的。
- 2. 构造函数的函数名必须与类名一致。
- 3. 构造函数并不是由我们手动调用 的,构造函数是在创建对应的对象的时候,jvm 主动调用的。
- 4. 每创建一个对象,就会调用一次对应的构造方法。
- 5. 如果一个类没有显式的写上一个构造函数的时候,那么java编译器会为该类添加 一个无参的构造方法。
- 6. 如果一个类已经显式的写上了一个构造方法,那么java编译器则不会再为该类添 加一个无参构造方法。
- 7. 一个类可以存在多个构造函数, 创建对象的时候具体调用哪个是根据你创建对象 的时候所传入参数而定。
- 1. 作用上的区别:
- 普通的函数的作用是用于描述一类事物的功能, 构造函数的作用初始化对 象。
- 2. 函数名的区别:
- 普通函数的函数名只要符合标识符的命名规则即可。 构造函数的函数名必须要 与类名一致。
- 3. 返回值类型的区别:
- 普通函数是有返回值类型的,而构造函数是没有返回值类型的。
- 4. 调用上的区别:
- 普通函数可以使用一个对象调用多次,构造函数是每创建一个对象就只会调用一 次。
- 注意:代码混淆
* 疑问1: 创建对象的时候jvm会调用构造方法,那么我们以前没有学构造方法,那么jvm 还会调用构造方法吗?
- 会,java编译器在编译一个java文件的时候,如果该类没有显式的写上一个构 造方法,那么java编译器会自动为该类添加 一个无参的构造方法。
* 疑问2: java编译器添加的无参构造方法默认的权限修饰符是什么?
- java编译器添加的无参构造方法的权限修饰符是与类的修饰符一致。
* jdk提供一个反编译工具给我们: javap
- 使用格式:
javap -c -l -private class
- 构造代码块 : 构造代码块的作用是给所有的对象进行统一初始化。
- 构造函数: 构造函数的作用是给对应的对象进行初始化。
- 构造代码块的实现方式:
{
构造代码块
}
- 构造代码块是在创建任意的对象的时候都会调用一次的。
构造代码块 : 构造代码块就是指{}位于方法之外,类之内的代码块。
局部代码块: {}位于方法之内的代码块。缩短局部变量的生命周期。
静态代码块: static修饰的代码块
- 静态代码块的代码是在class文件加载的时候调用的。
- 静态代码块的代码的使用场景:
- 用于加载配置文件: 比如:数据库的用户名密码加载。
- 1. 构造函数的代码是位于成员变量的显式初始化、构造代码块之后执行的。(不管 代码的位置如何摆放)
- 2 . 成员变量的定义语句经过java编译器编译之后,声明变量 的语句会被提前。
- 3. 其实构造代码块的代码是在构造函数里面执行的。(重点)
- 4. 构造代码块的代码与成员 变量的显式初始化动作的先后顺序是根据当前的代码顺 序而决定的。
(谁调用了this当前所在的函数,this就代表谁)
- 问题1: 构造函数的形式参数变量名一旦改成了id与name,那么赋值动作失效??
- 问题2: 构造函数中出现了重复代码 ?
- 1. 存在同名的成员变量与局部变量时, 在方法内部默认访问的是局部变量的数据, 可以通过this关键字指定访问成员变量的数据。
- 2. this关键可以在一个类的构造函数中调用另外一个构造函数初始化对象。
- 1. 如果在方法内部访问了一个变量,而该变量仅存在于成员变量上的时候,那么java 编译器会在该变量的前面添加 this关键字。
- 2. this关键字调用其他的构造函数的时候,this关键字必须是构造函数第一个语句.
- 3. this关键字调用构造函数的时候不准出现相互调用的情况,因为会死循环。
- 注意:this关键字可以用于引用当前类以外其他类型的对象
- static修饰的成员变量的数据是属于所有的对象共享的数据,在内存中只会维护一 份 。
- 方式一: 使用对象进行访问。
对象.属性名
- 方式二: 使用类名进行访问
类名.属性名
- 推荐使用: 类名访问。
- 1. 静态的成员变量可以使用类名与对象进行访问,而非静态的成员变量只能使用对 象进行访问。
- 2. 如果数据不是属于共享使用,那么千万不要为了访问方便而使用static修饰。只 有数据真正需要被共享的时候才使用static修饰。
- 1. 作用的区别:
- 静态的成员变量的作用是共享一个数据给所有对象使用,
- 非静态成员变量的作用是描述一类事物的公共属性。
- 2. 访问方式的区别:
- 静态的成员变量可以使用类名、 对象进行访问。
- 非静态的成员变量只能使用对象进行访问。
- 3. 生命周期的区别:
- 静态的成员变量是随着class文件的加载而存在,随着class文件卸载消失。
- 非静态的成员变量随着对象创建而存在,随着对象被垃圾回收器回收的时候 就消失。
- 4. 数量上区别:
- 静态的成员变量数据是存在于方法区内存中而且只会存在一份数据。
- 非静态的成员变量数据是存在于堆内存中,数量与对象一样。
- 方式一: 可以使用对象进行访问
对象.函数名()
- 方式二: 可以使用类名进行访问。
类名.函数名()
- 1. 静态函数可以使用类名、对象进行访问,非静态函数只能使用对象进行访问了。
- 2. 静态函数可以直接访问静态的成员,但是不能直接访问非静态的成员。
- 原因:静态函数可以使用类名进行调用,这时候有可能还没有存在对象,如果
对象不存在,那么就意味着非静态的数据还不存在内存中。
- 3. 非静态函数可以直接访问静态的成员,也可以直接访问非静态的成员.
- 原因: 非静态函数只能由对象进行调用,调用非静态函数时对象已经存在了
对象一旦存在,静态数据与非静态数据都已经在内存中了。
- 4. 静态函数是不准出现this与super关键字的。
- 原因: 静态函数可以使用类名进行调用,这时候不存在着函数的调用者对象。
- 结论: 静态的数据优先于非静态的数据存在内存
- 什么时候使用static修饰成员变量呢?
- 如果成员变量的数据是属于共享数据,那么这时候即可使用static修饰该成员变 量。
- 什么时候使用static修饰一个函数呢?
- 如果一个函数没有直接访问非静态的成员,那么就可以使用static修饰该函数。 例如:Arrrays工具类
* public : 公共,为了jvm在任何情况下都可以调用到main方法。
* static: 静态
* void : 没有返回值, 原因:因为main方法是由jvm调用的,如果设计成有返回值,那 么返回的数据就交给了jvm,但是jvm也不知道怎么去使用返回值,而且你也没 法获取到返回值。
* main: 不是一个关键字,只不过是jvm识别的一个比较特殊的标识符而已。
* args: 数组, 主要是用于传递参数使用的。
* main方法假如不用static修饰引起麻烦事:
- 1. 如果main方法不是static修饰的,那么调用main就需要先创建对象。----> jvm 就必须要创建对象。
- 2. 假如一个类不存在着无参的构造方法, jvm在创建对象的时候就必须要使用带 参的构造方法,而jvm这时候根本就不知道传入什么数据给你才合适。
- java是面向对象语言: 万物皆对象. 世界上任何的事物都可以使用java类进行描述。
- 在生活中事物与事物是有关系,那么java就必须要把事物之间的关系也要描述清楚。
- 目前存在的问题:
1. 目前狗与动物类的继承 关系没有描述清楚。
2. 两个类的代码重复了
class 类名1 extends 类名2 {
}
- 1.千万不要为了减少重复代码而去继承, 只有两种事物真正的存在继承关系的时候才 去继承。
- 2. 父类私有的成员是不能被继承的。
- 3. 父类的构造方法也是不能被继承。
- 4. 创建子类对象时默认会先调用父类无参的构造方法。
- 注意:一个类只能有一个直接的父类。
- 创建子类对象时为什么会调用父类的构造方法?
- 意义: 在创建子类对象时调用父类的构造方法的意义在于为子类初始化从父类 继承下来的属性数据。
- 问题: 父类的功能无法满足了子类的需求。
- 解决方案: 子类可以对该功能进行重写。
- 必须要存在着继承的关系。
- 子父类存在同名的函数称作为方法的重写。
1. 方法重写时,子父类的函数名与形式参数要完全一致。
2. 方法重写时, 子类的访问权限修饰符必须大于或者等于父类的权限修饰符。
3. 方法重写时, 子类的返回值类型必须要小于或者等于父类的返回值类型。
4. 方法重写时, 子类抛出的异常类型必须要小于或者 等于父类抛出的异常类型。
- 在一个类中存成两个或者两个以上 的同名函数称作为方法的重载。
- 1. 函数名一致。
- 2. 形式参数列表不一致。(形式参数的个数或对应的数据类型不一致。)
- 3. 与返回值类型无关
- 方法重载:在一个类中存成两个或者两个以上 的同名函数称作为方法的重载。
- 方法重写:子父类存在同名的函数称作为方法的重写。
- 1. 子父类存在着同名的成员时,在子类中默认访问的是子类的成员 ,可以通过super 关键字指定访问父类的同名成员。
2. super关键字可以在子类的构造函数中指定调用父类的构造函数。
- 1. super关键字调用父类 构造函数的时候,super关键字必须位于子类构造函数中 第一个语句。
- 2. super关键字与this关键字调用构造函数的时候不能同时存在一个构造函数中,因 为两个语句都需要是第一个语句。
- 1. 使用前提的区别: this关键字不需要存在继承关系就能使用,super关键字一定 要存在继承关系才能使用。
- 2. 作用上的区别 : this关键字代表的是所属函数的调用者对象,super关键字代表 的是父类空间的引用。
* 模式:解决一类问题的固定步骤。
- 模式的概念最先是建筑行业提出来的:
- 盖房子:
- 打地基----->浇柱 -----> 盖楼面-----> 砌墙 ------->装修----完工
- IT行业
- 砖家 -------> 24种设计模式
* 单例设计模式:
- 保证一个类在内存中只有一个对象。
- 1. 私有化构造函数。
- 2. 声明本类的引用类型变量并且让该变量指向本类的对象。
- 3. 提供一个公共静态的方法获取本类的对象
- 1. 私有化构造函数。
- 2. 声明本类的引用类型变量,但是先不要创建本类的对象。
- 3. 提供公共静态的方法获取本类的对象,获取之前先判断是否已经创建了本类 的对象,如果还没有创建,那么就先创建本类的对象然后返回,如果已经创建 了,那么直接返回即可。
- 推荐使用: 饿汉单例设计模式. 因为懒汉单例设计模式存在线程安全问题。
- 懒汉模式线程安全问题的解决办法:使用同步函数 synchronize()
- 判断的对象与类型必须要存在继承关系。
- 对象 instanceof 类型
- boolean flag = Dog instanceof Animal;
* instance of关键字的应用场景:
- 类型强制转换之前先判断是否是属于某种类型,这时候可以避免强制类型转换异常。
- 1. final修饰基本数据类型变量时, 该变量的值不能被修改。
- 2. final修饰引用类型变量时,该变量不能重新指向新的对象。
- 3. final修饰一个方法时,该方法不能被重写。
- 4. final修饰一个类的时候,该类不能被继承。
* 常量的命名规范:全部字母大写,单词与单词之间使用下划线分隔。
* 常量的修饰符: public static final
- 目前存在的问题:
- 1. Animal的run方法写得不合理。
- 2. 编译的时候没有强制让我重写run方法。
- 动物跑的行为不具体,例如:狗和鱼
- 我们在描述一类事物的时候,发现该事物确实存在着某种行为,但是目前这种行为是 不具体的,那么我们可以抽取这种行为的声明,不去实现该种行为,把这种实现描述 成抽象的行为,这时候即可使用抽象类。
- 1. 如果一个方法没有方法体,那么该方法必须要使用abstract修饰。
- 例:public void run(); 没有方法体,需要abstract修饰
- 2. 如果一个类存在着抽象方法,那么该类也必须要使用abstract修饰或者是接口。
- 3. 非抽象类继承抽象类的时候,要把抽象类的所有抽象方法全部实现。
- 4. 抽象类可以存在非抽象与抽象方法。
- 5. 抽象类可以不存在抽象方法。
- 6. 抽象类不能创建对象。
- 疑问:为什么抽象类不允许被创建对象呢?
- 因为抽象类存在着抽象方法,创建了抽象的对象就可以调用抽象方法,调用 抽象方法是没有任何意义。
- 7. 抽象类肯定存在构造方法的。
- 疑问: 既然抽象类都不能创建对象,那么存在构造方法的意义在哪?
- 其构造方法是提供给子类去调用初始化从父类继承下去的属性的。
- 1. abstract 不能与private共同修饰一个方法。
- 2. abstract 不能与static共同修饰一个方法。
- 3. abstract 不能与final 共同修饰一个方法。
- 调用一个方法的时候传递的变量,只不过是传递了变量所存储的值,并没有把变量的 本身传递过去。
- 注意:每一个方法运行的时候jvm都会为该方法开辟一个独立的内存空间, 不同内存空间上的变量是相互独立的。
interface 接口名{
}
- 接口中也可以有成员变量和成员函数,只是一般没人用而已。
- 1. 接口是一个特殊的类。
- 2. 接口中的成员变量都是常量,默认的修饰符为public static final .
- 3. 接口中的方法全部都是抽象方法,默认的修饰符为 public abstract。
- 4. 接口不能创建对象。
- 5. 接口是没有构造方法的。
- 6. 接口是给类实现使用的。
- 7. 非抽象类实现一个接口时, 必须要把接口中的所有方法实现。
- 1. 程序的解耦。
- 2. 定义约束规范。
- 3. 拓展功能的。
class 类名 implements 接口名{
}
- 注意
- 1. 非抽象类实现一个接口时,必须要把接口中所有方法实现。
-2. 抽象类实现一个接口时,可以实现接口中的方法,也可以不实现接口方法。
- 3. 一个类可以实现多个接口。 java支持多实现的 .
- 注意: 一个接口是可以继承多个接口
- 原因:
- 1. 主要是防止多个类有相同的方法名,然而方法体不一样,子类就比较难选择了。 所以java不支持类的多继承
- 2. 允许实现多个接口的一个好处就是,当实现多个接口时,如果两个接口有同样 的方法,那么实现一次就可以了。由于接口没有方法体,所以接口可以实现多 继承。
- 父类的引用类型变量指向了子类的对象或者是接口的引用类型变量指向 了接口实现类的对象。
- 1. 多态情况下,子父类存在着同名的成员变量时,默认访问的是父类的成员变量。
- 2. 多态情况下,子父类存在着同名的非静态函数时,默认访问的是子类的成员函数。
- 3. 多态情况下,子父类存在着同名的静态函数时, 默认访问的是父类的成员函数。
- 总结: 多态情况下,子父类存在着同名的成员时,默认都是访问父类的成员,除了 同名的非静态函数是访问子类的成员。
- 4. 多态情况下,不能调用子类特有的方法或者不能访问子类特有的成员变量。
- java编译器在编译的时候会检测一个引用类型变量所属的类是否具备指定的成员,如 果不具备那么编译报错。
- 1. 多态用于形式参数类型的时候可以接收更多类型的对象。
- 2. 多态用于返回值类型的时候可以返回更多类型的对象。
* 多态怎么调用子类的特有成员
- 多态最不爽的地方即使不能调用子类特有的成员。
- 多态情况下如果需要调用子类特有的成员需要进行类型强制转换。
- 例:Animal a = new Dog();
Dog d = (Dog)a;
d.bite();
* 类型转换:
- 基类数据类型数据
- 小类型数据--------->大类型数据 自动类型转换
- 大类型数据--------->小类型数据 强制类型转换
引用数据类型:
- 小类型数据--------->大类型数据 自动类型转换
- 大类型数据 -------->小类型数据 强制类型转换
- 在A类内部中定义另外一个B类,B类则称作为内部类。
- 注意: 内部类的class文件的命名是: 外部类$内部类.class . 这样子的命名意义 主要是为了区分开目前内部类是属于哪个外部类的。
- 成员内部类
- 局部内部类
- 匿名内部类
- 成员内部类的访问方式:
- 方式一: 在外部类提供一个方法用于创建内部类的对象,然后进行访问。
- 方式二:在其他类直接创建内部类的对象。
格式:
外部类.内部类 变量名 = new 外部类().new 内部类();
* 内部类的好处:
- 内部类可以直接访问外部类的任何成员。
* 内部类的应用场景:
- 我们在描述一类A事物的时候,发现该A事物内部还具备另外一个事物B,而且B 事物需要用到A事物的一些成员数据,那么这时候B事物我们就可以使用内部类来 描述。
- 比如:
class 人{
氧气
血液
class 心脏{
}
}
- 1. 如果外部类与内部类存在着同名的成员时,在内部类中默认是访问内部类的成员(就近原则)。如果需要指定访问外部类的成员,可以使用"外部类.this.成员"格式进行指定访问。
- 2. 如果一个内部类使用了private修饰,那么该内部类就只能在外部类提供 一个方 法创建内部类的对象了,在其他类无法再创建该内部类的对象。
- 3. 如果内部出现了静态的成员,那么该内部类也必须使用static修饰.
- 疑问: 为什么内部类出现了静态的成员,那么该内部类就必须使用static修饰??
- 在A类的方法内部定义另外一个B类 , B类则称作为局部内部类。
- 注意:局部内部类访问一个局部变量的时候,局部变量必须使用final修饰。
- 疑问:为什么局部内部类访问一个局部变量的时候,局部变量必须使用final修饰?
- 没有类名的内部类
* 匿名内部类使用前提:
- 必须存在继承或者实现关系。
* 匿名内部类的好处:
- 简化书写。
* 注意:匿名内部类只是没有类名,其他成员是具备的。
标签:
原文地址:http://www.cnblogs.com/youth99dream/p/4733385.html