现在的位置: 首页 > 综合 > 正文

java 面向对象一

2017年11月18日 ⁄ 综合 ⁄ 共 5329字 ⁄ 字号 评论关闭

一.面向对象概念
1.什么是对象:
现实社会中由各种各样的事物所组成, 而程序是模拟现实社会的, 在程序中表示这些事物, 就是使用对象.
万物皆对象.
2.面向对象特征:
封装, 抽象, 继承, 多态.
3.面向对象的优点:
将一类事物的特征和功能抽取, 写在一个类中, 定义成属性和方法.
之后根据类创建对象, 操作对象来完成对应的工作.
代码复用性高, 每次完成一个功能, 就是调用对象的方法.
使用者无需关心具体细节, 功能的实现是封装在方法中的, 程序员只要调用方法, 就可以完成工作.
转变程序员的角色, 更加符合人的思维习惯. 程序员变成一个指挥的角色, 需要哪类事物就可以创建哪类对象, 然后调用对象的方法.
4.类:
类是对象的抽象, 对象是类的实例.
5.创建对象:
使用new关键字可以根据类创建一个对象.

二.面向对象细节
1.成员变量和局部变量的访问
在类中直接定义的变量叫成员变量, 也可以叫做类的属性, 用来描述这一类对象的特征.
而如果在某个方法中定义和成员变量相同名字的局部变量, 那么在方法中以这个名字访问的话, 会优先找局部变量.
如果一定要访问类的成员变量, 可以在变量名前加 this. 
this是一个引用, 谁调用当前方法, 就引用谁.
2.对象创建过程
Person p = new Person(); 这一行代码都做了什么?
在栈内存中开辟空间, 起名叫p.
在堆内存中创建对象Person
初始化成员变量, 给成员变量赋默认值
将对象的地址赋值给p变量, p变量引用了new Person()对象
3.成员变量初始化的默认类型
基本数据类型都是0
引用数据类型都是null
4.对象的生命周期
对象的生命周期从new关键字创建时开始.
没有任何引用可以到达对象, 对象生命周期结束, 成为垃圾.
5.匿名对象
如果一个对象只使用一次, 我们就可以将其定义为匿名对象, 不用任何变量引用这个对象.
匿名对象的生命周期从创建开始, 使用一次之后就成为了垃圾.
匿名对象通常作为一个实参传递给方法.

三.封装
1.什么是封装
将一组对象共有的特征和功能总结成属性和方法, 写入一个类中, 这个类就可以用来描述这一组对象.
2.属性的封装
类的属性要使用private关键字修饰, 定义为私有化, 不能让其他类直接访问.
定义公有的get,set方法来访问类的属性.
3.方法的封装
有时候我们的方法也会定义为private, 只在当前类中调用.
例如电脑的开机方法, 有可能调用到了cpu的运行, 硬盘的运行, 等若干原件的运行. 
用户无需关心这些原件的运行方法, 只要调用电脑开机, 那么电脑开机方法中会调用这些方法.
这些方法就没有必要暴露出来了.

* 一.构造函数
1.构造函数的特征:
构造函数是一个特殊的函数, 在创建对象的时候运行
没有返回值类型
函数名和类名相同
不能在构造函数中返回一个值, 但可以使用return关键字结束函数
2.构造函数的执行过程
Person p = new Person();
先在栈内存创建变量p
加载类 Person.class
在堆内存创建对象
初始化成员变量, 引用数据类型是null, 基本数据类型是0
运行构造函数
变量p引用对象的地址
3.默认构造函数
只要创建对象, 一定会调用构造函数. 
如果不写任何构造函数, 会生成一个默认无参的空的构造函数.
如果写了任何一个构造函数, 就不会再生成默认的了.
为了方便别人创建对象, 当我们写有参构造函数时, 最好把无参的也写上. (标准的JavaBean)
4.构造函数的访问权限
一般构造函数都定义为public的, 所有类都能使用. 如不写则是默认, 默认权限只能相同的包中使用.
如果一个类不想让别人创建对象, 可以声明为private的构造函数. 例如: 单态设计模式
5.构造函数之间的调用
在构造函数中, 可以使用this()形式调用其他构造函数.
this()只能写在第一个语句.
注意不要形成递归调用.

* 二.this关键字
1.this的特征:
this用在方法中
是一个对象引用
谁调用方法, 就引用谁
2.this的应用场景:
a).指定调用类的成员的时候
b).构造函数中使用this()形式调用其他构造函数
c).将调用方法的对象本身作为一个参数传递给其他函数
d).在内部类中使用(以后再讲)

* 三.参数传递
1.基本数据类型
由于基本数据类型直接存储在变量中, 当做实参传入方法后, 方法中的形参里保存的就是基本数据类型的值.
在方法中对形参修改, 调用处的实参不受影响.
2.引用数据类型
由于引用数据类型是将地址存储在变量中, 当做实参传入方法后, 方法中的形参里保存的就是引用数据类型的地址.
在方法中对形参修改, 修改的是同一个地址上的对象, 所以调用处的实参也受影响.

四.Static
* 1.静态变量
静态变量被类的所有实例所共享
静态变量可以直接使用 类名.变量名 形式访问
静态变量在类加载时初始化. (类在第一次被使用的时候加载)
* 2.静态方法
静态方法在类加载后就可以使用
静态方法可以直接使用 类名.方法名 形式访问
静态方法中不能访问外部非静态成员. 因为静态方法在类加载后就可以使用了, 而其他非静态成员必须创建对象之后才能用.
如果一定要在静态方法中使用非静态成员, 可以先创建对象再使用
静态方法中不能使用this关键字, 因为this是一个引用, 哪个对象调用方法就引用哪个对象, 而静态方法有可能不被任何对象调用, 所以this有可能引用不到.
如果一个方法不需要访问该类的属性, 那么就可以定义为静态方法, 这样别人不用创建对象就可以直接访问方法, 方便别人使用.
3.静态代码块
类加载时就执行的代码
由于类只在第一次使用的时候加载, 静态代码块中的代码只执行一次
4.对象创建流程(最终版)
Person p = new Person();
栈内存创建变量
在名称空间中检查是否有Person.class, 有则不加载, 没有则加载
处理静态成员. 初始化静态变量, 运行静态代码块, 加载静态方法. 静态变量初始化和静态代码块顺序按代码从上到下顺序执行
堆内存创建对象, 初始化成员变量, 运行普通代码块, 加载非静态方法
运行构造函数
变量记住对象地址

五.垃圾回收
1.finalize()
在对象被销毁之前会自动调用finalize()方法
finalize()方法在每个类中都会有, 因为这个方法在Object类中定义.
Object是所有类的父类, 所有类都会继承Object类中的方法.
2.gc()
JVM虚拟机处理垃圾的机制是由垃圾的量来决定的, 当虚拟机中的垃圾对象足够多时, 就开始处理垃圾了.
如果我们想将虚拟机中的垃圾对象全部清除, 可以使用System.gc()方法通知虚拟机清理垃圾(需要时间).

一.内部类
1.什么是内部类
在类中定义的类, 就是内部类.
2.为什么使用内部类
如果创建一个类的对象需要先创建另一个类对象的时候, 就可以把这个类定义为内部类.
如果一个类想访问另一个类的成员, 也可以定义为另一个类的内部类.
3.创建内部类对象
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
Outer.Inner inner = new Outer().new Inner();
4.成员访问
内部类可以直接访问外部类的成员, 而外部类不能直接访问内部类的成员.
内部类对象创建之后, 外部类对象一定存在, 且肯定是一个, 所以内部类对象可以使用外部类对象的成员. 以 外部类名.this.成员名 形式访问
外部类对象则不能使用内部类对象, 因为外部类对象创建之后内部类对象有可能还没有创建, 就算创建, 也可能不止一个.
如果在外部类中一定要访问内部类的成员, 先创建一个内部类对象. 再通过对象访问其成员.
5.class文件名:
外部类名$内部类名.class

二.方法中的内部类
1.为什么类要定义在方法中:
如果一个类只在某个方法中使用, 那么就可以定义在方法中.
2.class文件名
外部类名$编号内部类名
3.使用方式
方法中的内部类必须先定义再使用, 定义的代码必须在使用的代码上面.
因为方法是从上到下运行的, 需要先运行到定义类的代码, 后面才能使用.
4.多个类嵌套使用
在方法中创建一个类的对象, 先会找方法中的内部类.
如果没有, 则会找普通内部类.
如果还没有, 则会找外部类.
再没有, 则报错.
5.访问局部变量
方法中的内部类不能直接访问方法中的局部变量.
因为内部类对象的生命周期有可能比局部变量生命周期要长. 局部变量在方法结束的时候, 就会被销毁. 而内部类对象仍然可能有其他引用到达.
为了在这种情况下不出错, 需要将局部变量的生命周期延长, 所以使用final修饰.
方法中的内部类访问方法中局部变量, 变量必须声明为final.

三.静态内部类
1.普通内部类的静态声明
普通内部类中不能有静态的声明.
静态的成员本意就是不创建对象(类加载后)就能使用.
而内部类必须要创建外部类对象才能使用, 如果在内部类中定义静态成员, 就违背了静态的本意.
2.静态内部类创建
创建静态内部类, 不需要创建外部类.
Outer.Inner inner = new Outer.Inner();
3.为什么使用静态内部类
如果一个内部类需要定义静态成员, 那么就可以使用静态内部类.
4.静态内部类中调用外部成员
静态内部类中不论是否静态的方法, 都不能调用外部非静态的成员.
因为静态内部类可以在不创建外部类的情况下创建对象, 没有外部类对象, 就不能调用外部类的成员.

***** 四.继承
1.什么是继承
一个类可以使用extends关键字继承另外一个类
被继承的类是父类(超类,基类)
继承的类是子类(派生类)
子类会自动继承父类所有的方法和属性
2.为什么用继承
当我们发现一个类的功能不够用时, 需要添加方法时.
当我们定义一个类时需要其他类的功能(方法)的时候.
代码复用
3.多个类继承
Java只支持单继承, 不支持多继承. 因为如果多个类有相同的方法, 都继承过来之后会产生冲突.
Java可以支持多重继承, 也就是一个类继承另一个类, 另一个再继承其他类.

五.类型转换
*** 1.向上转型
子类可以当做父类来用, 因为父类有的功能子类都有.
而父类不能当子类用, 因为子类有的父类不一定有.
在程序中可以使用一个父类类型的变量引用子类对象, 这叫向上转型.
在向上转型时, 使用父类变量, 不能调用子类特有方法. 因为编译器检查时会报语法错误.
*** 2.强制类型转换
在向上转型时, 使用父类变量引用子类对象, 不能调用子类特有方法, 如果一定要调用, 那么可以强制类型转换.
使用 (类型) 的形式将一个父类变量转换为子类变量.
在强制类型转换的时候, 编译器无法判断被转对象的类型. 这时如果被转对象不能强制转换为要转的类型, 运行时会报错.
为了避免这种错误, 我们一般在强转之前都要使用 instanceof 来判断一下要转的对象是否是指定类型.
3.向上转型时遇到的问题
在子类当做父类来用的时候, 用父类变量记住一个子类对象.
这种情况下, 使用父类变量调用方法, 会调用子类的方法, 因为这个变量中记住的是子类对象的地址. JVM虚拟机的动态绑定.
而这种动态绑定的机制没有被使用到类的属性中, 因为java希望我们将所有的属性私有化, 也就不会被继承, 就不会出现这种问题.

* 六.匿名内部类
1.什么是匿名内部类
如果一个类只使用一次, 那么就可以使用匿名内部类.
2.定义的格式
new 父类类型(){
类定义
}
这样做是做了两件事, 先定义了一个类继承于指定父类, 然后使用这个类创建了一个对象

*****类的说明符
 
1、类的访问说明符
   (1)public
   (2)default(不加访问说明符时)
2、类的其它修饰符
   (1)final     表明类为最终类,不能派生其它子类
   (2)abstract 抽象类
3、将目录下的所有源文件都编译生成:javac -d . *.java
   好处是不需要考虑哪个类先生成了。
4、class关键字前没有加任何访问说明符时,类为缺省类。不同包中的类无法访问。
5、在不同的包之间访问类时,只能访问到包中声明为public的类。
6、缺省的类访问说明符,表明类只能被同一包中的类访问。
 
方法的访问说明符
 
1、方法的访问说明符
   (1)public                    
   (2)protected                
   (3)default(不加访问说明符时)
   (4)private
        
              public    protected    default        private
    同类        v               v           v             v 
    同包        v               v           v
    子类        v               v
    不同包      v
        
2、方法的其它修饰符
   (1)static
   (2)final
   (3)abstract
   (4)native
   (5)synchronized
3、final方法:为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖
   (overridden),可以使用final方法。
4、抽象的方法和抽象类:
   *在类中没有方法体的方法就是抽象方法。
   *含有抽象方法的类,即为抽象类。
   *如果一个子类没有实现抽象基类中所有的抽象方法,则子类也成为一个抽象类。
   *我们可以将一个没有任何抽象方法的类声明为abstract,避免由这个类产生任何的对象。
   *抽象类需要声明abstract
 

【上篇】
【下篇】

抱歉!评论已关闭.