面向对象学习三条主线
》类与类的成员:属性、方法、构造器;代码块(或初始化块)、内部类
》面向对象的三个特征:封装性、继承性、多态性;(抽象性)
》其它关键字的使用:this super static final abstract interface package import...
一.类的成员之一类的属性(或成员变量)
1.成员变量与 局部变量的异同
1)相同点:①变量的声明: 数据类型 变量名 = 初始化值;
②都有其作用域,仅在作用域内有效
2)不同点:
①在类中声明的位置不同
>属性:直接定义在类的内部的变量
>局部变量:方法内定义的;方法的形参;代码块内部;构造器内部;。。。
②成员变量声明的数据类型前可以指明这个变量的权限:private 缺省 protected public
局部变量声明的数据类型前不可以有权限的声明。
③成员变量可以不显式的赋值,那么就会使用其默认赋值。
局部变量:除方法的形参之外,都需要显式的赋值,否则报错,方法的形参是在方法调用的时候赋值的。
④在内存中保存的位置不同:成员变量保存于堆空间;局部变量保存于栈空间
2.总结对一个属性的赋值执行顺序:
①默认初始化
②显式初始化或代码块中初始化(取决于声明的先后顺序)
③构造器中初始化
④ 一次或多次通过"对象.属性" 或 "对象.方法"的方式,对属性赋值。
二.类的成员之二类的方法 封装了一定功能的机构体。
方法声明的格式:权限修饰符 方法的返回值类型 方法名(形参列表){
//方法体;
}
权限修饰符:表明这个方法可以被调用的范围。java规定了4种不同的权限:
private 缺省 protected public
方法的返回值类型:void 或 有具体的返回值类型。
注:方法内可以调用本类中声明的其他的方法或属性,但是方法内不可以定义新的方法
三.对象及内存解析
创建一个类的多个对象,不同的对象之间没有关系,各自拥有一套类的“副本”:属性, 即:当对一个类的对象的属性修改值时,不会影响其它对象的属性的值。
四.方法的重载,重写与可变个数的形参
1.方法重载
两同一不同:同一个类中,相同方法名,不同参数列表的多个方法间构成重载
注:1.参数列表不同:参数的个数不同 或参数的类型不同
2.是否构成重载,与方法的返回值类型没有关系!
2.方法重写
当有了类的继承以后,子类可以对父类中声明的方法进行重写、覆盖、覆写。
方法的定义:权限修饰符 返回值类型 方法名(形参列表){//方法体}
①要求子类重写的方法与父类被重写的方法的“返回值类型 方法名(形参列表)”一样
②要求子类重写的方法的权限不小于父类被重写的方法的权限.注:子类不可以重写父类中声明为private的方法
③要求子类重写的方法抛出的异常类型不能大于父类被重写的方法抛出的异常
3.可变个数的形参
1)可变个数形参的格式:数据类型...变量名
2)当调用这个方法时,参数的个数可以是零个、一个或多个
3)可变个数的形参的方法与同名的方法构成重载
4)可变个数形参的格式与使用同类型数组的声明方式一样.不能同时出现在一个类的声明中
5)可变个数形参必须声明在方法形参的最后,一个方法中最多有一个可变个数的形参
五.java中参数传递机制
1.方法的形参:方法声明时的参数,实参:方法调用时实际传给形参的参数值
2.java的参数传递机制:值传递
1)当方法的形参是基本数据类型的变量时,将变量的值传递给方法的形参
2)当方法的形参是引用数据类型的变量(比如:类的对象名)时,将引用数据类型的变量的地址值传递给方法的形参
六.面向对象之封装
1.为什么需要封装
在实际问题,当我们通过"对象.属性"的方式对对象的属性进行赋值时,往往属性值的赋值范围因实际问题的需要,有一定的限制。但是我们又没有办法直接将这个限制体现在属性的声明处。所以,我们必须通过"对象.方法"的方式 实现。即:将对属性的限制写在方法中,通过调用方法来实现。同时,禁止对象来直接调用属性。
2.怎么封装
将类的属性私有化,同时提供公共的方式进行设置(setXxx(Xxx xxx))和获取(getXxx())。保证在类的外部,不能直接通过对象来调用属性。要想调用,必须通过方法!
3.java封装的四种权限 private 缺省 protected public
这4种权限都可以用来修饰类的成员:属性、方法、构造器、内部类
如果修饰类的话,只能使用缺省 、public的
七.类的成员之三构造器constructor
1.构造器的作用:①创建对象 ②初始化对象的属性值
2.说明: 1)当我们没有显式的在一个类中声明构造器的时候,系统会自动给我们提供一个空参的构造器=>任何一个类都有构造器!
2)如何创建一个构造器:权限修饰符 类名(形参列表){}
3)构造器可以重载
4)一旦当我们声明了类的构造器时,系统将不再给我们提供空参的构造器!
八.this关键字:当前对象或当前正在创建的对象
1.可以用来修饰属性、方法、构造器
2.在方法中调用当前类的属性或者其他方法,默认前面都有“this.”。只是说省略了而已。 但是有一种情况不能省略,那就是:当方法的形参名与类的属性名一样时,必须通过“this.”的方式,指明调用的是类的属性,而非形参的变量
3.this修饰构造器
在构造器中通过使用"this(形参列表)",显示的调用本类中重载的其它构造器
this(形参列表)"必须声明在构造器的首行!==>一个构造器中最多只能有声明一个"this(形参列表)"
若一个类中有n个构造器,那么最多有 n -1 个构造器中使用了"this(形参列表)"
九.javaBean
满足如下条件的java类就称作一个JavaBean
1.类是公共的 2.私有化类的属性,并提供公共的方法getter和setter3.至少提供一个空参的构造器
十.package和import
1.关键字:package:包
1.每一个ava源文件的第一行都指明这个文件的包名
2.定义包名的规则和规范:xxx.yyy.zzz
3.每"."一次,就表示一层文件目录。
2.关键字:import:导入 -----export:导出
1.使用import 可以显式的导入某个包下的类或接口,声明在package 和类的声明之间,如果需要导入多个其他包下的类,那么就并列写出即可
2.若导入的类或接口是本包下的或者是java.lang包下的,那么就可以省略此条import.
3."import java.util.*"表示可以导入util包下的所有声明过的类或接口
4.若一个类中引用了不同的包下的同名的两个类,那么至少其中一个需要使用全类名的方式来引用。比如:java.util.Date 和 java.sql.Date
5.import static:显式的导入某个类或接口中的静态结构:属性、方法
import static java.lang.Math.PI;
十一.面向对象之继承
1.为什么有继承
减少了代码的冗余,提高了代码的复用性
2.继承说明
1)格式:class A extends B。其中,A:子类(subClass),B:父类(superClass)
2)继承以后的特点:通过子类继承父类,就获取了父类中声明的所有结构:属性、方法、构造器。特别说明的:子类可以获取父类中声明的私有的结构,只是由于封装性的影响,不可以直接调用罢了。
3)java中类的继承的要求:单继承性!即一个子类只能有一个父类。
4)如果一个类没有显式的继承另外一个类的话,默认继承于java.lang.Object类。=>java.lang.Object类是所有其它类的父类(根基类)
3.子类对象实例化的全过程
Cylinder cylinder = new Cylinder();
当我们创建一个子类的对象时,一定会直接或间接的调用父类的构造器,进而将父类中声明的属性或方法加载到内存里,供子类对象所使用。
十二.super关键字:调用父类中的结构
1.可以用来修饰属性、方法、构造器
2.“super.属性” 或 "super.方法":显式的调用父类中声明的属性或方法。
尤其是,子父类中出现同名的属性 或 需要在子类的方法中调用父类中被重写的方法时。
3.super修饰构造器
1)使用"super(形参列表)"表示:显式的调用父类中声明的构造器
2)"super(形参列表)"必须声明在构造器的首行
3)在一个构造器的首行"this(形参列表)" 和 "super(形参列表)"只能出现一个
4)如果在构造器的首行没有显式的声明"this(形参列表)" 和 "super(形参列表)",那么 构造器默认调用父类的"super()"的构造器。
补充:子类继承父类以后,可以对方法进行重写、覆盖。但是属性不存在覆盖。
十三.面向对象之多态
1.多态性,可以理解为一个事物的多种形态。那么在java中的体现为:
广义上:方法的重载和重写;子类对象的多态性
狭义上:子类对象的多态性:父类的引用指向了子类的对象。Object obj = new String();
2.子类对象的多态性使用的前提:①要有类的继承关系 ②子类重写父类中的方法
只适用于方法。意味着属性不存在多态性
3.java程序分为编译状态(javac.exe)和运行状态(java.exe)
当使用子类对象的多态性时,编译时:看左边。运行时:看右边.
//子类对象的多态性
Person p = new Man();
//虚拟方法调用:编译时看左边,运行时看右边
p.eat();
p.walk();
//p.drink();
4.提升为父类的对象,可以通过强制类型转换符,再转换为子类的对象。
为了转换过程中,不会出现ClassCastException,必须在强转前使用instanceof关键字判断
Object obj = new String("AA");
Date date = (Date)obj;//在运行时,会报ClassCastException
应该改为:
Object obj = new String("AA");
if(obj instanceof Date){
Date date = (Date)obj;
}
5.多态的应用
十四. static关键字的使用
1.static:静态的,可以用来修饰属性、方法;代码块、内部类
2. static修饰属性(如 Math.PI;):
1)使用static修饰的变量,被类的多个对象所共用。在内存中只有一份!
2)我们可以通过"对象.类变量"的方式调用类中静态的属性
3)当类的一个对象将类变量进行修改的话,会影响到其它对象对这个类变量的调用。
4)static修饰的变量存在于静态域中。
5)非静态的属性随着对象的创建而分配内存(即:加载), 静态的属性随着类的创建而加载的。
6)类变量可以直接通过“类.类变量”的方式进行调用。而"类.实例变量"方式是不允许的。
7)类变量的生命周期的产生要早于实例变量,消亡也要晚于实例变量。
3. static修饰方法:类方法(或静态方法)
1)类方法随着类的加载而加载
2)可以通过"类.类方法"的方式进行调用,而"类.非静态的方法"就不可以调用
3)可以通过“对象.类方法”的方式对静态的方法进行调用。
4)静态方法内只能调用类中静态的结构:类属性、类方法,反之,非静态的方法内,可以调用类中静态的结构或者非静态的结构。
>在static修饰的方法内,不能使用this和super关键字
4.静态属性的内存解析
5.在设计一个类的时候,要考虑什么样的结构适合声明为static的。(经验)
>当这个结构的值不依赖于具体的对象而不同的时候;换句话说,多个对象适合共用这一个结构时,那么这个结构适合声明静态的
比如:Circle类中设计的total变量,用于记录创建的对象的个数。Math类中的PI。
>往往操作静态属性的方法,通常设计为静态的。比如:getter 和 setter
>当一个类中没有属性时,可以考虑将方法声明为静态的。比如:Arrays,Collections工具类
十五.类的成员之四代码块
1.主要作用:对类或对象的结构进行初始化操作
2.代码块分为静态代码块 和 非静态代码块
静态代码块:
1.随着类的加载而加载,只会被加载一次
2.可以调用当前类的静态结构:属性、方法,不可以调用非静态的结构
3.多个静态代码块之间按照先后顺序执行
4.静态代码块的加载要早于非静态代码块的加载。
非静态代码块:
1. 随着对象的创建而被加载,每创建一个对象,都会被加载一次。
2.既可以调用当前类的静态结构:属性、方法,又可以调用非静态的结构
3.多个非静态代码块之间按照先后顺序执行
十六.final关键字
1.final:最终的,可以用来修饰类、变量、方法
2.final修饰类:表示这个类不能被继承。比如:String类
final修饰方法:表示这个方法不能被重写。比如:Object类中的getClass()
final修饰变量:表示此变量变为一个常量。常量的名字通常都是大写。
可以给声明为final的属性赋值的位置:显示初始化;代码块中;构造器中
3.static final:全局常量。比如:Math类中的PI
十七.abstract关键字:抽象的,用来修饰类、方法
1.abstract修饰类:抽象类
1)抽象类不可实例化
2)抽象类仍然是有构造器的==>凡是类,都有构造器
3)抽象类中可以没有抽象方法。反之,抽象方法所在的类一定是抽象类
2.abtract修饰方法:抽象方法:只保留了方法的声明,而没有方法功能的实现
1)子类继承抽象的父类以后,若重写了所有的抽象方法,那么就是一个"实体"的类,即可以实例化
2)子类继承抽象的父类以后,若没有重写所有的抽象方法,那么这个子类仍然是一个抽象类,不可实例化
3.abstract不能用来修饰属性、构造器;
abstract不能与private \ final \ static共用。
十八.接口的使用
1.接口,是与类并列的一个概念,是对一定功能的封装,只体现功能的声明,不提供具体功能的实现。
2.接口,可以看成是抽象方法与常量的集合。换句话说,接口中只能定义常量和抽象方法。
常量:默认使用public static final修饰
抽象方法:默认使用public abstract修饰
3.接口中没有构造器,接口不可以实例化。
4.类与接口间的关系:实现关系。
class A extends B implements C{}
若实现类A中重写了接口中的所有的抽象方法,那么类A就可以实例化
若实现类A中没有重写接口中的所有的抽象方法,那么类A仍然是一个抽象类,不可实例化。
5.java中规定,类与类之间可以有继承关系,而且是单继承的!(局限性)
当时java规定,一个类可以实现(implements)多个接口,在一定程度上,缓解了单继承的局限性。
6.接口与接口之间也是继承关系,而且可以多继承!
7.接口定义与实现方式
十九.类的成员之五内部类
1.在Java中,允许一个类A的定义位于另一个类B的内部,前者类A称为内部类(InnerClass),后者类B称为外部类(OuterClass)。
2.分类:成员内部类(静态的成员内部类 、 非静态的成员内部类) vs 局部内部类
3.成员内部类: 一方面,作为外部类的成员:①可以声明为4种不同的权限 ②可以使用static修饰③可以调用外部类的属性、方法
另一方面,作为类:①内部可以声明属性、方法、构造器。。。 ②final 或 abstract修饰
4.内部类的学习需要专注的三个点:
1.如何实例化成员内部类的对象(静态与非静态的成员内部类的实例化方式不同)
2.如何区别调用不同的变量,尤其是外部类和内部类的属性、形参重名时
3.关于常见的局部内部类的使用。
举例: