面向对象
1.面向对象 vs 面向过程
2.面向对象编程的三条主线:
1)类及类的构成成分:属性 方法 构造器 代码块 内部类
2)面向对象编程的特征: 封装性 继承性 多态性 (抽象性)
3)其他的关键字:this super package import static final abstract interface ......
3.类及对象
3.1类的组成成分
1)属性(成员变量,field)
2)方法(成员方法,函数,Method)
3.2属性
成员变量 vs 局部变量
相同点:1.遵循变量声明的格式:数据类型 变量名 = 初始化值
2.都有作用域
不同点:1.声明的位置不同: 成员变量:声明在类里,方法外
局部变量:声明在方法内,方法的形参部分,代码块内
2.成员变量的修饰符有四个:public private protected 缺省
局部变量没有修饰符,与所在的方法修饰符相同
3.初始化值:一定会有初始化值
成员变量:如果在声明的时候,不显示的赋值,那么不同数据类型会有不同的默认初始化值
1)byteshort int long而言:0
2)float double 而言:0.0
3)char而言:空格
4)boolean而言:flase
5).引用类型变量而言:null
局部变量:一定要显示的赋值,(局部变量没有默认初始化值)
4.二者在内存中存放的位置不同:成员变量存在于堆空间中,局部变量:栈空间中
总结:关于变量的分类:1)按照数据类型不同:基本数据类型(8种) & 引用数据类型
2)按照声明的位置不同:成员变量 & 局部变量
3.3方法:提供某种功能的实现
1)实例:publicvoid eat(){//方法体}
public String getName(){}
publicvoid setName(String n){}
格式:权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){}
2)关于返回值类型:void:表明此方法不需要返回值
有返回值的方法:在方法的最后一定有return+返回值类型对应的变量
记忆:void与return不可以同时出现一个方法内,像一对"冤家"
3)方法内可以调用本类的其他方法或属性,但是不能在方法内再定义方法
3.4面向对象编程的思想的落地法则一:
1)设计并创建类及类的成分
2)实例化类的对象
3)通过"对象.属性"或"对象.方法"的形式完成某项功能
3.5类的初始化的内存解析
3.5.1内存划分的结构
栈(stack):局部变量、对象的引用名、数组的引用名
堆(heap):new出来的"东西" (如:对象的实体,数组的实体),含成员变量
方法区:含字符串常量
静态区:声明为static的变量
4.方法的重载(overload)
要求:1.同一个类中 2.方法名必须相同 3.方法的参数列表不同(参数的个数不同 参数类型不同)
补充:方法的重载与方法的返回值类型没有关系!
5.可变个数的形参的方法:
1)格式:对于方法的形参:数据类型...形参名
2)可变个数的形参的方法与同名的方法之间构成重载
3)可变个数的形参在调用时,个数从0开始,到无穷多个都可以
4)使用可变多个形参的方法与方法的形参使用数组是一致的
5)若方法中存在可变个数的形参,那么一定要声明在方法形参的最后
6).在一个方法中,最多声明一个可变个数的形参
6.java的值传递机制
方法的参数传递:
1.形参:方法声明时,方法小括号内的参数
实参:调用方法时,实际传入的参数的值
2.规则:java中的参数传递机制:值传递机制
1)形参是基本数据类型的:将实参的值传递给形参的基本数据类型的变量
2)形参是引用数据类型的:将实参的引用类型变量的值(对应的堆空间的对象实 体的首要地址值)传递给形参的引用
7.面向对象的特征一:封装与隐藏
7.1问题:当创建了类的对象以后,如果直接通过"对象.属性"的方式对相应的对象属性赋值的话,可能会出现不满足实际情况的意外,我们考虑不让对象来直接作用属性,而是通过"对象.方法"的形式,来控制对象对属性的访问,实际情况中,对属性的要求就可以通过方法来体现.
7.2面向对象思想的落地法则二:
(封装性的思想) 1)将类的属性私有化 2)提供公共的方法(setter &getter)来实现调用.
7.3四种权限修饰符:
1).权限从大到小为:publicprotected 缺省 private
2)四种权限都可以修饰属性、方法、构造器
3)修饰类的话:public 缺省
8.构造器
8.1构造器的作用:
1)创建对象 2)给创建的对象的属性赋值
1).设计类时,若不显式声明类的构造器的话,程序会默认提供一个空参的构造器
2)一旦显示的定义类的构造器,那么默认的构造器就不再提供
3)如何声明类的构造器,格式:权限修饰符 类名(形参){}
4)类的多个构造器之间构成重载
8.2类对象的属性赋值的先后顺序:
1)属性的默认初始化 2)属性的显式初始化 3)通过构造器给属性初始化4)通过"对象,方法"的方式给属性赋值
9.this关键字
1).使用在类中,可以用来修饰属性、方法、构造器
2).表示当前对象或者是当前正在创建的对象
3)当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量时类成员
4)在任意方法内,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的阅读性
5)在构造器中使用"this(形参列表)"显式的调用本类中重载的其他的构造器
1).要求"this(形参列表)"要声明在构造器的首行
2).类中若存在n个构造器,那么最多有n-1构造器中使用了this.
10.面向对象的特征二:继承
10.1子类继承父类以后,父类中声明的属性、方法,子类就可以获取到
明确:当父类中私有化的属性或方法时,子类同样可以获取得到.只是由于封装性的设计,使得子类不可以直接调用罢了.
子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分
extends:子类是对父类功能的"扩展",明确子类不是父类的子集
10.2java中类的继承性只支持单继承:一个类只能继承一个父类,反之,一个父类可以有多个子类
10.3 子父类是相对概念
10.4 方法的重写
---(方法的重载) 修饰符 返回值类型 方法名(参数列表){}
10.4.1 前提:有子类继承父类
10.4.2 子类继承父类以后,若父类的方法对子类不适用,那么子类可以对父类的方法重写(override overwrite)
10.4.3方法的重载与重写的区别:
重载:两同一不同:同一个类,同一个方法名,不同参数列表. 注:方法的重载与方法的返回值无关! 构造器是可以重载的
重写:(前提:在继承的基础之上,子类在获取了父类的结构以后,可以对父类中同名的方法进行"重构")
重写的规则:
1)要求子类方法的"返回值类型 方法名 (参数列表)"与父类的方法一致
2)子类方法的修饰符不能小于父类方法的修饰符
3)若父类方法抛异常,那么子类方法跑得异常类型不能大于父类的
4).子父类的方法必须同为static或非static.
10.5关键字super
1)super,相较于关键字this,可以修饰属性、方法、构造器
2)super修饰属性、方法:在子类的方法、构造器中,通过super.属性或者super.方法,显示调用父类的指定属性或方法,尤其是,当子类与父类有同名的属性、或方法时,"super."
3)通过"super(形参列表)",显示的在子类的构造器中,调用父类指定的构造器!
>任何一个类(除Object)的构造器的首行,要么显式的调用本类中重载的其他的构造器"this(形参列表)"或显式的调用父类中指定的构造器"super(形参列表)",要么默认的调用父类空参的构造器"super()"
>建议在设计类时,提供一个空参的构造器!
10.6子类对象实例化的全过程
先调用父类中的构造方法,然后再执行子类中的自己的构造方法
10.7面向对象的特征三:多态性
10.7.1多态的表现
1)方法的重载与重写 2)子类对象的多态性
10.7.2使用的前提
1)要有继承关系 2)要有方法的重写
10.7.3父类引用指向子类对象
格式:Person p = new Man();//向上转型
p.eat();
p.walk();
1)当调用方法时,实际执行的是子类重写父类方法
2)编译时,认为p是person类型的,故只能执行Person里才有的结构,即Man里特有的结果不能够用
3)子类对象的多态性,并不使用于属性
4)关于向下转型:向下转型,使用强转符:()
为了保证不报ClassCastException,最好在向下转型前,进行判断:instanceof
10.8 Object类
1)java.lang.Object类,是所有类的根父类!
2)Object类仅有一个空参的构造器 public Object(){}
3)关于方法:
equals(Objectobj)
只能处理引用类型变量
在Object类,发现equals()任然比较的两个引用变量的地址值是否相等
像String包装类File类Date类这些重写Object类的equals()方法,比较是两个对象的"实体内容"是否完全相同.
若我们自定义一个类,希望比较两个对象的属性值都相同的情况下返回true的话,就需要重写Object类的equals(Object obj)方法.
10.8.1判断符:==
基本数据类型:根据基本数据类型的值判断是否相等.相等返回true,反之返回false
注:两端数据类型可以不同,在不同的情况下,也可以返回true.
引用数据类型:比较引用类型变量的地址值是否相等
10.9 toString()方法
当我们输出一个对象的引用时,会调用toString()方法.
1.publicString toString(){
returngetClass().getName()+"@"+Integer.toHexString(hashCode());
}
当我们没有重写Object类的toString()方法时,打印的就是对象所在的类,以及对象实体在堆空间的位置
2.一般我们需要重写Object类的toString()方法,将此对象的各个属性值返回
3.像String类、Date、File类、包装类都重写了toString()方法.
10.10 1)static:静态的,可以用来修饰属性、方法、*代码块(或初始化块)、*内部类
2)static修饰属性(类变量):
1.由类创建的所有的对象,都共用这一个属性
2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用.vs实例变量(非 static修饰的属性,各个对象各自拥有自己的属性值)
3.类变量随着类的加载而加载的,而且独一份
4.静态的变量可以直接通过"类.类变量"的形式来调用
5.类变量的加载是要早于对象.所以当有对象以后,可以"对象.类变量"使用.但是"类.实例变 量"是不行的
6.类变量存在于静态域中
3)static修饰方法(类方法):
1.随着类的加载而加载,在内存中也是独一份
2.可以直接通过"类.类方法"的方式调用
3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法.反之,非静态的方法时可以调用静态的属性或静态方法 >静态的方法内是不可以有this或super关键字的!
注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要更早于非静态的结构,同时被收回也要晚于非静态的结构
10.10.1单例模式(java总共23种设计模式)
单例模式:
解决问题:如何只让设计的类只能创建一个对象
如何实现:饿汉式 & 懒汉式
//饿汉式1
class Bank{
//1.私有化构造器
privateBank(){}
//2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性
//4.要求此对象也为static的
privatestatic Bank instance = new Bank();
//3.此公共的方法,必须为static
publicstatic Bank getInstance(){
retruninstance;
}
}
//饿汉式2
class Bank{
//1.私有化构造器
privateBank(){}
//2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性
//4.要求此对象也为static的
privatestatic Bank instance = null;
static{
instance = new Bank();
}
//3.此公共的方法,必须为static
publicstatic Bank getInstance(){
retruninstance;
}
}
//懒汉式
class Bank{
privateBank(){}
privatestatic Bank instance = null;
publicstatic Bank getInstance(){
if(instance== null){ //可能存在线程安全问题
instance= new Bank():
}
returninstance;
}
}
10.11 main()方法
public static void main(String[] args){
//方法体
}
//1.main()是一个方法,是主方法,为程序的入口
//2.权限修饰符:publicproyected 缺省 private ---面向对象的封装性
//3.对于方法来讲:staticfinal abstract
//4.方法的返回值:void /具体的返回值类型(基本的数据类型 &引用数据类型),方法内 部一定要有return
//5.方法名:命名的规则:xxxYyyZzz.给方法命名时,要见名知意
//6.形参列表:同一个方法名不同的形参列表的诸多个方法间构成重载. 形参&实参 --- 方法的参数传递机制:值传递
//7.方法体:方法定义的是一种功能,具体的实现由方法体操作
10.12 代码块
代码块:是类的第4个成员(初始化块)
作用:用来初始化类的属性
分类:只能用static来修饰
静态代码块:
1)里面可以有输出语句
2)随着类的加载而加载,而且只被加载一次
3)多个静态代码块之间按照顺序结构执行
4)静态代码块的执行要早于非静态代码块的执行
5)静态的代码块中只能执行静态的结构(类属性、类方法)
非静态代码块:
1)可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的)
2)里面可以有输出语句
3)一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行
4)每创建一个类的对象,非静态代码块就加载一次
5)非静态代码块的执行要早于构造器
关于属性赋值的操作:
1)默认的初始化
2)显示初始化或代码块初始化(此处两个结构按照顺序执行)
3)构造器中
---------------以上是对象的属性初始化的过程---------------
4)通过方法对对象的相应属性进行修改
10.13 final关键字
final:最终的,可以用来修饰类、属性、方法
1).final修饰类:这个类就不能被继承.如:String类、StringBuffer类、System类
2).final修饰方法:不能被重写.如:Object类的getClass()
3)final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值.习惯上,常量用 大写字符表示.此常量在哪里赋值: a.此常量不能使用初始化 b.可以显式的赋值、代 码块、构造器
变量用staticfinal修饰:全局变量.比如:Math类的PI
10.24 抽象:abstract
abstract:抽象的,可以用来修饰类、方法
1.abstract修饰类:抽象类
1)不可被实例化
2)抽象类有构造器(凡是类都有构造器)
3)抽象方法所在的类,一定是抽象类
4)抽象类中可以没有抽象方法
>当我们设计一个类,不需要创建此类的实例时候,就可以考虑将其设置为抽象的,由其子类实现这个类的抽象方法
2.abstract修饰方法:抽象方法
1)格式:没有方法体,包括{},如:publicabstract void eat();
2)抽象方法只能保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法
3)若子类继承抽象类,并重写了所有的抽象方法,则此类事一个"实体类",即可以实例化
4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象类!
10.24.1模板方法设计模式
//模板方法设计模式
public class TestTemplate {
publicstatic void main(String[] args) {
newSubTemplate().spendTime();
}
}
abstract class Template {
publicabstract void code();
publicvoid spendTime() {
longstart = System.currentTimeMillis();
this.code();
longend = System.currentTimeMillis();
System.out.println("花费的时间为:"+ (end - start));
}
}
class SubTemplate extends Template {
publicvoid code() {
booleanflag = false;
for(inti = 2;i <= 10000;i++){
for(intj = 2;j <= Math.sqrt(i);j++){
if(i% j == 0){
flag= true;
break;
}
}
if(!flag){
System.out.println(i);
}
flag= false;
}
}
}
10.25 接口interface
接口(interface)是与类并行的一个概念
1.接口可以看做是一个特殊的抽象类.是常量与抽象方法的一个集合,不能包含变量、一般的方法.
2.接口是没有构造器的
3.接口定义的就是一种功能.此功能可以被类所实现(implements).
比如:class CCextends DD implements AA
4.实现接口的类,必须要重写其中的所有抽象方法,方可实例化.若没有重写所有的抽象方法,则此类仍为一个抽象类
5.类可以实现多个接口.------java中的类的继承是单继承的
6.接口与接口之间也是继承的关系,而且可以实现多继承
7.接口与具体的实现类之间也存在多态性
10.26工厂设计模式
//接口的应用:工厂方法的设计模式
public class TestFactoryMethod {
publicstatic void main(String[] args) {
IWorkFactoryi = new StudentWorkFactory();
i.getWork().doWork();
IWorkFactoryi1 = new TeacherWorkFactory();
i1.getWork().doWork();
}
}
interface IWorkFactory{
WorkgetWork();
}
class StudentWorkFactory implementsIWorkFactory{
@Override
publicWork getWork() {
returnnew StudentWork();
}
}
class TeacherWorkFactory implementsIWorkFactory{
@Override
publicWork getWork() {
returnnew TeacherWork();
}
}
interface Work{
voiddoWork();
}
class StudentWork implements Work{
@Override
publicvoid doWork() {
System.out.println("学生写作业");
}
}
class TeacherWork implements Work{
@Override
publicvoid doWork() {
System.out.println("老师批改作业");
}
}
10.26代理模式
//接口的应用:代理模式(静态代理)
public class TestProxy {
publicstatic void main(String[] args) {
Objectobj = new ProxyObject();
obj.action();
}
}
interface Object{
voidaction();
}
//代理类
class ProxyObject implements Object{
Objectobj;
publicProxyObject(){
System.out.println("代理类创建成功");
obj= new ObjctImpl();
}
publicvoid action(){
System.out.println("代理类开始执行");
obj.action();
System.out.println("代理类执行结束");
}
}
//被代理类
class ObjctImpl implements Object{
@Override
publicvoid action() {
System.out.println("=====被代理类开始执行======");
System.out.println("=====具体的操作======");
System.out.println("=====被代理类执行完毕======");
}
}10.27 内部类
类的第5个成员:内部类
1.相当于说,我们可以在类的内部再定义类.外面的类:外部类.里面定义的类:内部类
2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里)
3.成员内部类
3.1是外部类的一个成员: 1)可以有修饰符(4) 2)static final 3)可以调用外部类的属性、方法
3.2具体类的特点:1)abstract 2)还可以在其内部定义属性、方法、构造器
4.局部内部类:
5.关于内部类,大家掌握三点:
1)如何创建成员内部类的对象 (如何Bird类和Dog类的对象
2)如何区分调用外部类、内部类的变量(尤其是变量重名时)
3)局部内部类的使用
本文深入探讨面向对象编程的核心概念,包括封装、继承与多态性,并详细解析类与对象的构成、方法重载与重写、构造器、this与super关键字等关键知识点。
179

被折叠的 条评论
为什么被折叠?



