黑马程序员 java 基础 毕向东 第5天 面向对象
3 面向对象
----------------------------------------------------------华丽的分界线---------------------------------------------------
3.1 面向对象介绍
3.1.1 理解面向对象 面向对象相对面向过程而言;都是一种思想 面向过程 强调的是功能行为。 面向对象 将功能封装进对象,强调具备了功能的对象; 面向对象基于面向过程。 面向对象特征:封装、基础、多态 类:对现实事物的描述 对象:就是这类事物,实实在在的个体 映射到Java中,描述就是class 定义的类 具体对象就是对应jaa堆内存中用new 建立的实体 3.2.1 类与对象 Car c=new Car(); 成员变量和局部变量 两者具有不同的作用范围。 成员变量作用于整个类中。 局部变量作用于函数或语句中。 在内存中存储也不同: 成员变量在堆内存中,因为对象的存在,而局部变量存在栈内存中。 3.2.6 匿名对象 匿名对象时对象的简化方式 使用方式1:当对象的方法只调用一次。可以用匿名对象来完成。 如果对一个对象进行多个成员调用,必须给这个对象起名字。 使用方式2:可以讲匿名对象作为实际参数进行传递。3.3 封装 encapsulation
隐藏对象的属性和实现细节,仅仅对外提供公共访问方式。 好处:将变化隔离、便于使用、提高重用性、安全性 封装原则:将不需要对外提供的内容隐藏 把属性都隐藏,提供公共方法对其访问。 private:私有,权限修饰符,用于修饰类中的成员(成员变量。成员函数) 私有只在本类中有效。 之所以对外提供访问方式,就以为可以再访问方式中加入逻辑判断,对访问数据进行操作, 提高代码健壮性。 将成员变量私有化,对外提供对应的set ,get 方法对其进行访问。 提高对数据访问的安全性。3.4 构造函数
特点: 函数名与类名相同 不用定义返回值类型 不可以写return语句 作用: 给对象进行初始化。 注意: 1. 默认构造函数的特点。 2. 多个构造函数是以重载的形式存在的。 对象一建立就会调用与之对应的构造函数。 当类中没有定义构造函数,那么系统会默认给该类加入一个空参数的构造函数。 当定义后,默认构造函数就没有了; 构造代码块: 作用:给对象进行初始化。 对象一建立就进行,而且优先于构造函数执行。 和构造函数的区别: 构造代码块是给所以对象进行统一初始化。 而构造函数式给对应对象进行初始化。 构造代码块中定义不同对象共性的初始化;3.5 this关键字
特点:this代表其所在函数所属对象的引用。 即this代本类对象的引用。 当在函数内需要用到调用该函数的对象时,就用this。 用于区*部变量和成员变量; this 在构造函数中调用,只能放在构造函数第一行。 《黑马程序员_毕向东_Java基础视频教程第05天》 该天视频内容主要介绍了java面向对象特性,成员变量、局部变量、构造函数以及this关键字的特点。3.6 static(静态)关键字
用于修饰成员(成员变量和成员函数)被修饰后的成员具备以下特点:随着类的加载而加载 、随着类的消失而消失,即生命周期最长;优先于对象存在 、被所有对象所共享 、可以直接被类名调用 使用注意 :1:静态方法只能访问静态成员 ,非静态方法既可以访问静态也可以访问非静态。2 : 静态方法中不可以写this,super关键字3 : 主函数是静态的 实例变量和类变量的区别:1:存放位置 类变量随着类 的加载而存在于方法区中 实例变量随着对象的建立而存在于堆内存中2:生周期 类变量生命周期最长,随着类的消失而消失 实例变量生命周期随着对象的消失而消失public static void main(String[] args)主函数是一个特殊的函数,作为程序的入口,可以被jvm调用主函数的定义:public 代表该函数访问权限是最大的static 代表主函数随着类的加载就已经存在。void 主函数没有具体返回值;main 不是关键字,但是特殊的单词,可以被jvm识别args[] 函数参数:参数类似是字符串数组,传入 new String[0]格式固定什么时候使用静态:
要从两方面考虑:因为静态修饰的内容有成员变量和函数什么时候定义静态变量呢?:当对象中出现共享数据时什么时候定义静态函数呢?:当功能内部没有访问到非静态数据,那么该功能可以定义成静态的;静态 的应用----工具类 虽然可以通过建立Tool 的对象使用这些工具方法,对数组进行操作但发现了问题:1:对象用于封装数据,可是Tool 中并没有封装特有数据2: 操作数据的每一个方法没有用到Tool的对象的特有数据
这时就考虑,让程序更严谨,是不是需要对象可以讲Tool 中 的方法都定义成static ,直接通过类名调用。将方法都静态后,可以方便使用,但该类还是可以被其他程序建立对象;为了更加严谨,强制让该类不能建立对象可以通过将构造函数私有化完成;
----------------------------------------------------------华丽的分界线---------------------------------------------------
帮助文档的制作:
java 说明书通过文档注释来完成/**这是一个可以对数组进行操作的工具类,@author 张三@version 1.1*//**获取一个整数数组的最大值@param arr 接收一个int 类型的数组@return 会返回一个该数组中的最大值*/命令:javadoc -d 指定命令 -author -version ArrayTool.javaArrayTool 必须用public 修饰权限帮助文档也称api (Application program interface)静态代码块:
static { 静态代码块中的执行语句; }特点:随着类的加载而执行,只执行一次用于给类进行初始化执行顺序:静态代码块-----》构造代码块------》构造函数
对象的初始化过程;
Person p=new Person();1:因为new 用到了Person.class 所以会先找到Person.class 文件并加载到内存中2:执行该类的的static 代码块,3:在堆内存中开辟空间,分配内存地址4:在堆内存中建立对象的特有属性,并进行默认初始化5:对属性进行显示初始化6:对对象进行构造代码块初始化7:对对象进行对应的构造函数初始化8:将内存地址付给栈内存中的p变量对象调用成员过程
p.setName("d" );设计模式(有23种)偏思想:最初在建筑领域,解决某一类问题最行之有效的方法。单例设计模式:
解决一个类在内存中只存在一个对象;想要保证对象唯一:1:为了避免其他程序过多建立对象,先控制禁止其他程序建立该类对象2:为了让其他程序可以访问该类对象,只好在本类中自定义一个对象3:为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式代码体现:1:将构造函数私有化 private Car(){}2:在类中创建本类对象3:提供一个方法可以获取到该对象--------------------------------------------------------饿汉式:Single 类一进内存,就已经创建好了对象class Single { private static Single s=new Single(); private Single(){} public static Single getInstance(){ if(s==null) s=new Single(); return s;}}
--------------------------------------------------------对象是方法被调用时,才初始化,也叫做对象的延时加载,也叫懒汉式class Single { private static Single s=null; private Single(){} public static Single getInstance(){ if(s==null){ synchronized (Single.class){ if(s==null) s=new Single; } } return s;}}//定义单例,建议使用恶汉模式《黑马程序员_毕向东_Java基础视频教程第06天》该天的内容讲解了man函数、静态使用情景、工具类、帮助文档、静态代码块。对象初始化过程、对象调用成员过程、单例模式。其中单例模式在开发中有着重要应用地位。
----------------------------------------------------------华丽的分界线---------------------------------------------------
4 继承 is a
将共性描述提取出来。单独描述1:提高了代码 复用性2:是类与类直接产生了关系,有了关系,才 有了 多态的特性java 语言中:只支持单继承,不支持多继承因为多继承容易带来安全隐患当多个父类中定义了相同功能,子类对象不知道运行哪一个但是java保留了这中机制,并用另一种形式来完成;java继承多层继承,也就是一个继承体系如何使用一个继承体系中的功能:先查询体系父类的描述,通过了解共性功能,就可以知道该体系基本功能聚集关系:has a根据紧密程度分为:聚合:组合:跟紧密
子父类中变量的特点:
1:变量子类中出现非私有的同名成员变量时,子类要访问本类中的变量 用this 访问父类中的变量 用supersuper代表父类对象的应用子父类中函数的特点-覆盖(重写)当子类中出现和父类一模一样的函数时,会运行子类函数的内容,就好像父类的函数被覆盖一样注意:子类覆盖父类 必须保证 子类权限大于等于父类权限,否则编译失败;静态只能覆盖静态重载只看同名函数的参数列表重写是 子父类方法要一模一样
子父类中构造函数的特点--子类实例化过程
子类实例化时,父类构造函数先运行,因为子类构造函数第一行有 隐式 代码 super();super() 会访问父类空参数的构造函数,而且子类所有的构造函数第一行都有 隐式 代码 super();
为什么 子类一定要访问父类的构造函数:因为父类中的数据,子类可以直接获取,所以在建立时需要先查看父类是如何对这些数据进行初始化的;所以子类在对象初始化时,要先访问父类中的构造函数如果要父类指定的构造函数,可以手动定义super 语句子类所以构造函数默认都会访问父类中空参数的构造函数当父类中没有空参数的构造函数时,子类必须手动 super语句形式来指定要访问的构造函数;当然。子类的构造函数第一行可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数访问父类的构造函数;
final 关键字
final 可以修饰类 方法 变量final :最终被final修饰的类不可以被继承为了避免被继承,被子类复习功能被final修饰的方法不可以被复写被final修饰的变量时常量,只能赋值一次,既可以修饰成员变量,也可以是局部变量。当在描述事物时,一些数据的出现值是固定的,那么为了增强阅读性,给这些值命名方便阅读,而这些数据不需要改变,所以加final修饰作为常量,常量的书写规范:所以字母都大写,如果由多个单词组成,之间用_连接内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量;----------------------------------------------------------华丽的分界线---------------------------------------------------
抽象类:
当多个类中出现相同功能,但是功能主题不同,这时可以向上抽取,这时,只抽取功能定义,不抽取功能主体;抽象类的特点:1:抽象方法必须放在抽象类;2:抽象方法和抽象类都必须被abstract修饰3:抽象类不可以用new 创建对象,4:抽象类中的方法要被使用,必须由子类复习所有抽象方法,建立子类对象调用;如果子类只覆盖了部分抽象方法,那么该子类还是抽象类;抽象类中基于抽象方法也有非抽象方法;抽象类和一般类没有太大不同;抽象类比一般类多了抽象方法抽象类不可被实例化特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。abstract class Student{ abstract final void study(); //abstract void study1(); void sleep() { System.out.println("躺着"); }}/*
class ChongCiStudent extends Student{ void study() { System.out.println("chongci study"); }}
class BaseStudent extends Student{ void study() { System.out.println("base study"); }}
class AdvStudent extends Student{ void study() { System.out.println("adv study"); }}*/class AbstractDemo{ public static void main(String[] args) { //new Student(); //new BaseStudent().study(); }}
模板方法模式:
需求:获取一段代码运行的时间原理:获取程序开始和结束时间,最后相减什么是模板方法:在定义时,功能的一部分是确定的,而一部分是不确定的,而确定的部分使用不确定的部分;那么 将不确定部分暴露,有该类的子类完成,abstract class GetTime{ public final void getTime() { long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start)); } public abstract void runcode();
}
class SubTime extends GetTime{
public void runcode() { for(int x=0; x<4000; x++) { System.out.print(x); } }}
class TemplateDemo{ public static void main(String[] args) { //GetTime gt = new GetTime(); SubTime gt = new SubTime(); gt.getTime(); }}
----------------------------------------------------------华丽的分界线---------------------------------------------------
4.8接口
接口:初期理解,可以认为是一个特殊的抽象类 当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。接口定义特点:1:接口中常见定义:常量,抽象方法2:接口中的成语都有固定修饰符常量:public static final方法:public abstract接口中的成语都是public接口不可以创建对象,需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。
接口的特点:是对外暴露的规则是程序的功能扩展可以用来多实现类与接口是实现关系、类可以继承一个类的同时实现多个接口;接口与接口直接可以有继承关系;接口之间可以有继承关系;
《黑马程序员_毕向东_Java基础视频教程第07天》该天内容 介绍了面向对象思想中的继承,以及子父类成员的关系,介绍了抽象类、接口丰富了java体系。
----------------------------------------------------------华丽的分界线--------------------------------------------------- ----------------------------------------------------------华丽的分界线--------------------------------------------------- ----------------------------------------------------------华丽的分界线---------------------------------------------------