网站维护 网站后台建设知识,网站开通银行支付接口,网站内容建设情况,网站策划专员第四章#xff1a;面向对象编程
4.1#xff1a;面向过程与面向对象 面向过程(POP)与面向对象(OOP) 二者都是一种思想#xff0c;面向对象是相对于面向过程而言的。面向过程#xff0c;强调的是功能行为#xff0c;以函数为最小单位#xff0c;考虑怎么做。面向对象…第四章面向对象编程
4.1面向过程与面向对象 面向过程(POP)与面向对象(OOP) 二者都是一种思想面向对象是相对于面向过程而言的。面向过程强调的是功能行为以函数为最小单位考虑怎么做。面向对象将功能封装进对象强调具备了功能的对象以类/对象为最小单位考虑谁来做。 面向对象的三大特征 封装Encapsulation、继承Inheritance、多态Polymorphism 面向对象的思想概述 程序员从面向过程的执行者转化成了面向对象的指挥者面向对象分析方法分析问题的思路和步骤 根据问题需要选择问题所针对的现实世界中的实体。从实体中寻找解决问题相关的属性和功能这些属性和功能就形成了概念世界中的类。把抽象的实体用计算机语言进行描述形成计算机世界中类的定义。即借助某种程序语言把类构造成计算机能够识别和处理的数据结构。将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
4.2Java的基本元素类和对象 类Class和对象Object是面向对象的核心概念 类是对一类事物的描述是抽象的、概念上的定义。对象是实际存在的该类事物的每个个体因而也称为实例(instance)。面向对象程序的重点是类的设计。设计类就是设计类的成员。 Java类及类的成员 属性对应类中的成员变量。Field 属性 成员变量行为对应类中的成员方法。Methon (成员)方法 函数 类的语法格式 修饰符 class 类名{属性声明;方法声明;
}class Person{// 属性String name;int age 1;boolean isMale;// 方法public void eat(){System.out.println(人可以吃饭);}public void sleep() {System.out.println(人可以睡觉);}public void talk(String language) {System.out.println(人可以说话使用的是 language);}
}4.3对象的创建和使用 创建对象 类名 对象名 new 类名();Person p1 new Person();调用对象的结构属性、方法 属性对象名.属性 p1.name Tom;
p1.isMale true;方法对象名.方法 p1.eat();
p1.sleep();
p1.talk(Chinese);注意如果创建了一个类的多个对象对于类中定义的属性每个对象都拥有各自的一套副本且互不干扰。 内存解析 堆Heap此内存区域的唯一目的就是存放对象实例几乎所有的对象实例都在这里分配内存。栈(Stack)是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用。方法执行完自动释放。方法区(Method Area)用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 匿名对象的使用 理解我们创建的对象没有显式的赋给一个变量名。即匿名对象。特征匿名对象只能调用一次。使用 如果对一个对象只需要进行一次方法调用那么就可以使用匿名对象。我们经常将匿名对象作为实参传递给一个方法调用。
4.4类的成员之一:属性 语法格式 修饰符 数据类型 属性名 初始化值;成员变量与局部变量 在方法体外类体内声明的变量称为成员变量。在方法体内部声明的变量称为局部变量。 成员变量(属性)和布局变量的区别 成员变量局部变量声明的位置直接声明在类中方法形参或内部、代码块内、构造器内等修饰符private、public、static、final等不能用权限修饰符修饰可以用final修饰初始值有默认初始化值没有默认初始化值必须显示赋值方可使用内存加载位置堆空间或静态域内栈空间 对象属性的默认初始化赋值 当一个对象被创建时会对其中各种类型的成员变量自动进行初始化赋值。 数组元素类型元素默认初始化值byte0short0int0long0Lfloat0.0Fdouble0.0char0或\u0000booleanfalse引用类型null
4.5类的成员之二:方法 什么是方法(函数) 方法是类或对象行为特征的抽象用来完成某个功能操作。在某些语言中也称为函数或过程。将功能封装为方法的目的是可以实现代码重用简化代码。Java里的方法不能独立存在所有的方法必须定义在类里。 声明格式 修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ....) {方法体程序代码;return 返回值;
}public void eat() {System.out.println(客户吃饭);
}public void sleep(int hour) {System.out.println(休息了 hour 个小时);
}public String getName() {return name;
}public String getNation(String nation) {String info 我的国籍是 nation;return info;
}说明 返回值类型 如果方法有返回值则必须在方法声明时指定返回值的类型。同时方法中需要使用return关键字来返回指定类型的变量或常量return 数据。如果方法没有返回值则方法声明时使用void来表示。通常没有返回值的方法中就不需要使用return。但是如果使用的话只能return;表示结束此方法的意思。 return关键字的使用 使用范围使用在方法体中。作用 结束方法。针对于有返回值类型的方法使用return 数据方法返回所要的数据。 注意点return关键字后面不可以声明执行语句。 方法的使用中可以调用当前类的属性或方法特殊的方法A中又调用了方法A【递归方法】。方法中不可以定义方法。 方法的分类 方法的分类按照是否有形参及返回值 无返回值有返回值无形参void 方法名() {}返回值的类型 方法名() {}有形参void 方法名(形参列表) {}返回值的类型 方法名(形参列表) {} 方法的重载 定义在同一个类中允许存在一个以上的同名方法只要他们的参数个数或者参数类型不同即可。 两同一不同同一个类、相同方法名参数列表不同【参数个数不同参数类型不同】。 判断是否是重载 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系 可变个数的参数 JavaSE 5.0中提供了Varargs(variable number of arguments)机制允许直接定义能和多个实参相匹配的形参。从而可以用一种更简单的方法来传递个数可变的实参。 可变个数形参的格式数据类型 ... 变量名当调用可变个数形参的方法时传入的参数个数可以是0个、1个、2个…可变个数形参的方法与本类中方法名相同形参不同的方法之间构成重载。可变个数形参的方法与本类中方法名相同形参类型也相同的数组之间不构成重载。换句话说二者不能共存。可变个数形参在方法的形参中必须声明在末尾。可变个数形参在方法的形参中最多只能声明一个可变形参。 方法参数的值传递机制 方法必须由其所在类或对象调用才有意义。若方法含有函数 形参方法声明时的参数。实参方法调用时实际传给形参的参数值。 java的实参值如何传入方法 Java里方法的参数传递方式只有一种:值传递。即将实际参数值的副本(复制品)传入方法内而参数本身不受影响 形参时基本数据类型将实参基本数据类型变量的数据值传递给形参。形参时引用数据类型将实参引用数据类型变量的地址值传递给形参。 递归方法 递归方法一个方法体内调用它自身。方法递归包含了一种隐式的循环它会重复执行某段代码但这种重复执行无须循环控制。递归一定要向已知方法递归否则这种递归就变成了无穷递归类似于死循环。
4.6封装与隐藏 高内聚、低耦合 高内聚类的内部数据操作细节自己完成不允许外部干涉。低耦合仅对外暴露少量的方法用于使用。 隐藏对象内部的复杂性只对外公开简单的接口。便于外界调用从而提高系统的可扩展性、可维护性。通俗的说把该隐藏的隐藏起来该暴露的暴露出来。这就是封装性的设计思想。 信息的封装和隐藏 Java中通过将数据声明为私有的private在提供公共的public方法getXxx()和setXxx()实现对该属性的操作以实现下述目的 隐藏一个类中不需要对外提供的实现细节。使用者只能通过事先定制好的方法来访问数据可以方便地加入控制逻辑限制对属性的不合理操作。便于修改增强代码的可维护性。 public class AnimalTest {public static void main(String[] args) {Animal a new Animal();a.name 大黄;a.show();a.setLegs(6);a.setLegs(-6);a.show();System.out.println(a.name);}}class Animal{String name;private int age;private int legs;public void setLegs(int l) {if(l 0 l % 2 0) {legs l;} else {legs 0;}}public int getLegs() { return legs; }public int getAge() { return age; }public void setAge(int a) { age a; }public void eat() {System.out.println(动物进食);}public void show() {System.out.println(name name , age age , legs legs);}}四种访问权限修饰符 Java权限修饰符public、protected、(缺省)、private置于类的成员定义前用于来限定对象对该类成员的访问权限。 修饰符类内部同一个包不同包的子类同一个过程privateYes(缺省)YesYesprotectedYesYesYespublicYesYesYesYes总结 修饰类的话只能使用缺省、publicJava提供了4种权限修饰符来修饰类及类的内部结构体现类及类的内部结构在被调用时的可见性的大小。
4.7类的成员之三:构造器 构造器的作用 创建对象。初始化对象的信息。 格式 权限修饰符 类名(形参列表) {}说明 如果没有显示的定义类的构造器的话则系统默认提供一个空参的构造器。一个类中定义的多个构造器彼此构成重载。一旦我们显示的定义类的构造器之后系统就不再提供默认的空参构造器。一个类中至少会有一个构造器。 代码示例 public class PersonTest {public static void main(String[] args) {Person p1 new Person();p1.eat();Person p2 new Person(Tom);System.out.println(p2.name);}}class Person{String name;int age;// 构造器public Person() {System.out.println(Person()....);}public Person(String n) {name n;}public Person(String n, int a) {name n;age a;}}属性赋值过程 赋值的位置 默认初始化显式初始化构造器中初始化通过对象.属性或对象.方法的方式赋值。 赋值的先后顺序1 - 2 - 3 - 4 JavaBean JavaBean是一种Java语言写成的可重用组件。所谓JavaBean是指符合如下标准的Java类 类是公共的。有一个无参的公共的构造器。有属性且有对应的get、set方法。 用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能而不用关心任何改变。
4.8this的使用 this关键字的使用 this可以用来修饰、调用属性、方法、构造器。 this修饰属性和方法 this理解为当前对象或当前正在创建的对象。 在类的方法【或构造器】中我们可以使用this.属性或this.方法的方式调用当前对象【或当前正在创建的】对象属性或方法。但是通常情况下我们都选择省略this.。特殊情况下如果方法【构造器】的形参和类的属性同名时我们必须显式的使用this.变量的方式表名此变量是属性而非形参。 this调用构造器 我们在类的构造器中可以显式的使用this(形参列表)方式调用本类中指定的其他构造器。构造器中不能通过this(形参列表)方式调用自己。如果一个类中有n个构造器则最多有n - 1构造器中使用了this(形参列表)。规定this(形参列表)必须声明在当前构造器的首行。构造器内部最多只能声明一个this(形参列表)用来调用其他的构造器。
4.9关键字:package、import package关键字的使用 为了更好的实现项目中类的管理提供包的概念。使用package声明类或接口所属的包声明在源文件的首行。包属于标识符遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”每.一次就代表一层文件目录。 补充同一个包下不能命名同名的接口、类。不同的包下可以命名同名的接口、类。 MVC设计模式 MVC是常用的设计模式之一将整个程序分为三个层次视图模型层、控制器层、与数据模型层。这种将程序输入输出、数据处理以及数据的展示分离开来的设计模式使程序结构变的灵活而且清晰同时也描述了程序各个对象间的通信方式降低了程序的耦合性。 模型层model主要处理数据 数据对象封装model.bean/domain数据库操作类model.dao数据库model.db 控制层controller处理业务逻辑 应用界面相关controller.activity存放fragmentcontroller.fragment显示列表的适配器controller.adapter服务相关的controller.service抽取的基类controller.base 视图层view显示数据 相关工具类view.utils自定义viewview.ui import关键字的使用 在源文件中显式的使用import结构导入指定包下的类、接口。声明在包的声明和类的声明之间。如果需要导入多个结构则并列写出即可。可以使用xxx.*的方式表示可以导入xxx包下的所有结构。如果使用的类或接口是java.lang包下定义的则可以省略import结构。如果使用的类或接口是本包下定义的则可以省略import结构。如果在源文件中使用了不同包下的同名的类则必须至少有一个类需要以全类名的方式显示。使用xxx.*方式表名可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构则仍需要显式导入。import static导入指定类或接口中的静态结构属性或方法。
4.10继承性 继承性的好处 减少了代码的冗余提高了代码的复用性。便于功能的扩展。为之后多态性的使用提供了前提。 继承性的格式 class A extends B {}
// A:子类、派生类、subclass
// B:父类、超类、基类、superclass体现一旦子类A继承父类B以后子类A中就获取了父类B中声明的所有的属性和方法。 特别的父类中声明为private的属性或方法子类继承父类以后仍然认为获取了父类中私有的结构。只是因为封装性的影响使得子类不能直接调用父类的结构而已。 子类继承父类以后还可以声明自己特有的属性或方法实现功能的拓展。 Java中关于继承性的规定 一个类可以被多个子类继承。Java中类的单继承性一个类只能有一个父类。子父类是相对的概念。子类直接继承的父类称为直接父类。间接继承的父类称为间接父类。子类继承父类以后就获取了直接父类以及所有间接父类中声明的属性和方法。如果我们没有显示的声明一个类的父类的话则此类继承于java.lang.Object类。所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类。意味着所有的java类具有java.lang.Object类声明的功能。
4.11方法的重写 重写 子类继承父类以后可以对父类中同名同参数的方法进行覆盖操作。 应用 重写以后当创建子类对象以后通过子类对象调用子父类中的同名同参数的方法时实际执行的是子类重写父类的方法。 重写的规定 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型 {// 方法体
}
// 约定俗称子类中的叫重写的方法父类中叫被重写的方法子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同。 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符。 特殊情况子类不能重写父类中声明为private权限的方法。 返回值类型 父类被重写的方法的返回值类型是void则子类重写的方法的返回值类型只能是void。父类被重写的方法的返回值类型是A类型则子类重写的方法的返回值类型可以是A类或A类的子类。父类被重写的方法的返回值类型是基本数据类型则子类重写的方法的返回值类型也是相同的基本数据类型 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型。 注意子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写)要么都声明为static的(不是重写)。
4.12super关键字 super理解为 父类的 super可以用来调用 属性、方法、构造器 super调用属性和方法 我们可以在子类的方法或构造器中。通过使用super.属性或super.方法的方式显式的调用父类中声明的属性或方法。但是通常情况下我们习惯省略super。特殊情况当子类和父类中定义了同名的属性时我们要想在子类中调用父类中声明的属性则必须显示的使用super.属性的方式表明调用的是父类中声明的属性。特殊情况当子类重写了父类中的方法以后我们想在子类的方法中调用父类中被重写的方法时则必须显式的使用super.方法的方式表明调用的是父类中被重写的方法。 super调用构造器 我们可以在子类的构造器中显式的使用super(形参列表)的方式调用父类中声明的指定的构造器。super(形参列表)的使用必须声明在子类构造器的首行。我们在类的构造器中针对于this(形参列表)或super(形参列表)只能二选一不能同时出现。在构造器的首行没有显式的声明this(形参列表)或super(形参列表)则默认调用的是父类中空参的构造器super()在类的多个构造器中至少有一个类的构造器中使用了super(形参列表)调用父类中的构造器。 this和super的区别 区别点thissuper访问属性访问本类中的属性如果本类没有此属性则从父类中继续查找直接访问父类中的属性调用方法访问本类中的方法如果本类没有此方法则从父类中继续查找直接访问父类中的方法调用构造器调用本类构造器必须放在构造器的首行调用父类的构造器必须放在子类构造器的首行
4.13多态性 理解多态性 可以理解为一个事物的多种形态。 何为多态性 对象的多态性父类的引用指向子类的对象(或子类的对象赋给父类的引用) 父类 变量名 new 子类();多态的使用 虚拟方法调用 有了对象的多态性以后我们在编译器只能调用父类中声明的方法但在运行期我们实际执行的是子类重写父类的方法。 总结编译看左边运行看右边。 多态性的使用前提 类的继承关系方法的重写 对于对象的多态性只适用于方法不适用于属性(编译和运行都看左边) instanceof关键字 // 对象a是类A的实例返回true不是返回false
boolean flag a instanceof A;使用情境 为了避免在向下转型时出现ClassCastException的异常我们在向下转型之前先进行instanceof的判断一旦返回true就向下转型。如果返回false不进行向下转型。 子类 变量名 (子类) 父类对象;4.14Object类的使用
Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类则默认父类为java.lang.Object类。Object类中的功能(属性、方法)就具有通用性。
public class ObjectTest {public static void main(String[] args) {Order order new Order();System.out.println(order.getClass().getSuperclass());}
}
class Order {}Object类中的主要结构 方法名称类型描述public Object()构造构造器public boolean equals(Object obj)普通对象比较public int hashCode()普通取得Hash码public String toString()普通对象打印时调用 equals方法的使用 是一个方法而非运算符只能使用于引用数据类型。 Object类中equals()的定义和的作用是相同的比较两个对象的地址值是否相同。 public boolean equals(Object obj) {return (this obj);
}通常情况下我们自定义类的如果使用equals()的话也通常是比较两个对象的实体内容是否相同。那么我们就需要对Object类中的equals()进行重写。 toString的使用 当我们输出一个对象的引用时实际上就是调用当前对象的toString()。 Object类中toString()的定义 public String toString() {return getClass().getName() Integer.toHexString(hashCode());
}自定义类也可以重写toString()方法当调用此方法时返回对象的实体内容。
4.15包装类的使用
java提供了8种基本数据类型对应的包装类使得基本数据类型的变量具有类的特征。 基本数据类型、包装类、String三者之间的相互转换 public class WrapperTest {//String类型 ---基本数据类型、包装类调用包装类的parseXxx(String s)Testpublic void test5(){String str1 123;int num2 Integer.parseInt(str1);System.out.println(num2 1);}//基本数据类型、包装类---String类型调用String重载的valueOf(Xxx xxx)Testpublic void test4(){ int num1 10;//方式1调用String的valueOf(Xxx xxx)float f1 12.3f;String str2 String.valueOf(f1);System.out.println(str2);}// JDK 5.0 新特性自动装箱 与自动拆箱Testpublic void test3(){//自动装箱基本数据类型 ---包装类int num2 10;Integer in1 num2;//自动装箱//自动拆箱包装类---基本数据类型System.out.println(in1.toString());int num3 in1;//自动拆箱}//包装类---基本数据类型:调用包装类Xxx的xxxValue()Testpublic void test2(){Integer in1 new Integer(12);int i1 in1.intValue();System.out.println(i1 1);}//基本数据类型 ---包装类调用包装类的构造器Testpublic void test1(){ int num1 10;Integer in1 new Integer(num1);System.out.println(in1.toString());}}4.16static关键字
static可以用来修饰属性、方法、代码块、内部类。 使用static修饰属性静态属性 我们创建了类的多个对象多个对象共享同一个静态变量。当通过某一个对象修改静态变量时会导致其他对象调用此静态变量时是修改过了的。静态变量随着类的加载而加载。可以通过类.静态变量的方式进行调用。静态变量的加载要早于对象的创建。由于类只会加载一次则静态变量在内存中只会存在一份存在方法区的静态域中。 使用static修饰方法静态方法 随着类的加载而加载可以通过类.静态方法的方式进行调用。静态方法中只能调用静态的方法或属性。非静态方法中可以调用非静态的方法或属性也可以调用静态的方法或属性。 static注意点 在静态的方法内不能使用this关键字、super关键字。关于静态属性和静态方法的使用大家都从生命周期的角度去理解。 单例设计模式 所谓类的单例设计模式就是采取一定的方法保证在整个的软件系统中对某个类只能存在一个对象实例。 饿汉式和懒汉式 饿汉式 public class SingletonTest1 {public static void main(String[] args) {Bank bank1 Bank.getInstance();Bank bank2 Bank.getInstance();System.out.println(bank1 bank2);}
}class Bank {// 私有化类的构造器private Bank() {}// 内部创建类的对象private static Bank instance new Bank();// 提供公共的静态的方法返回类的对象。public static Bank getInstance() {return instance;}
}懒汉式 public class SingletonTest2 {public static void main(String[] args) {Order order1 Order.getInstance();Order order2 Order.getInstance();System.out.println(order1 order2);}
}class Order {// 私有化类的构造器private Order() {}// 声明当前类对象没有初始化private static Order instance null;// 声明public、static的返回当前类对象的方法public static Order getInstance() {if(instance null) {instance new Order();}return instance;}}饿汉式和懒汉式的区别 饿汉式 坏处对象加载时间过长。 好处饿汉式是线程安全的。 懒汉式 好处延迟对象的创建。 单例模式的应用场景 网站的计数器。应用程序的日志应用。数据库连接池。项目中读取配置文件的类。Application也是单例的典型应用。Windows的Task Manager(任务管理器)就是很典型的单例模式。Windows的Recycle Bin(回收站)也是典型的单例应用。
4.17代码块
代码块的作用是用来初始化类、对象。代码块如果有修饰的话只能使用static。 静态代码块 格式 static{语句;
}随着类的加载而执行而且只执行一次。 作用初始化类的信息。 如果一个类中定义了多个静态代码块则按照声明的先后顺序执行。 静态代码块的执行要优先于非静态代码块的执行。 静态代码块内只能调用静态的属性、静态的方法不能调用非静态的结构。 非静态代码块 格式 {语句;
}随着对象的创建而执行。 每创建一个对象就执行一次非静态代码块。 作用可以在创建对象时对对象的属性等进行初始化。 如果一个类中定义了多个非静态代码块则按照声明的先后顺序执行。 非静态代码块内可以调用静态的属性、静态的方法或非静态的属性、非静态的方法。 对属性可以赋值的位置 默认初始化。显示初始化 / 在代码块中赋值。构造器中初始化。有了对象以后可以通过对象.属性或对象.方法的方式进行赋值。
4.18final关键字
final可以用来修饰的结构类、方法、变量。 final用来修饰一个类 此类不能被其他类所继承。 final用来修饰方法 表明此方法不可以被重写。 final用来修饰变量 此时的变量就称为是一个常量。 final修饰属性 可以考虑赋值的位置有显示初始化、代码块中初始化、构造器中初始化。 final修饰局部变量 尤其是使用final修饰形参时表明此形参是一个常量。当我们调用此方法时给常量形参赋一个实参。一旦赋值以后就只能在方法体内使用此形参但不能进行重新赋值。
4.19抽象类与抽象方法
随着继承层次中一个个新子类的定义类变得越来越具体而父类则更一般更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象以至于它没有具体的实例这样的类叫做抽象类。
其中要把一个类变成抽象类的话要使用关键字abstract。abstract可以用来修饰的结构有类方法。 abstract修饰类 格式 权限修饰符 abstract class 类名 {}此类不能实例化。 抽象类中一定有构造器便于子类实例化时调用。【子类对象实例化的全过程】 开发中都会提供抽象类的子类让子类对象实例化完成相关的操作。 abstract修饰方法 格式 权限修饰符 abstract 返回值类型 方法名(形参列表);抽象方法只有方法的声明没有方法体。 包含抽象方法的类一定是一个抽象类。反之抽象类中可以没有抽象方法的。 若子类重写了父类中的所有的抽象方法后此子类方可实例化。若子类没有重写父类中的所有的抽象方法则此子类也是一个抽象类需要使用abstract修饰。 abstract注意点 abstract不能用来修饰属性、构造器等结构。abstract不能用来修饰私有方法、静态方法、final的方法、final的类。 抽象类的匿名子类 public class PersonTest{ public static void main(String[] args) {new Person() {public void eat(){System.out.println(人要吃有营养的食物);}public void walk(){System.out.println(人走路);}};}
}abstract class Person {String name;int age;public Person() {}public Person(String name, int age) {this.name name;this.age age;}public abstract void eat();public abstract void walk();
}模板方法设计模式 在软件开发中实现一个算法时整体步骤很固定、通用这些步骤已经在父类中写好了。但是某些部分易变易变部分可以抽象出来供不同子类实现。这就是一种模板模式。 public class BankTemplateMethodTest {public static void main(String[] args) {BankTemplateMethod btm new DrawMoney();btm.process();BankTemplateMethod btm2 new ManageMoney();btm2.process();}
}abstract class BankTemplateMethod {public void takeNumber() {System.out.println(取号排队);}public abstract void transact();public void evaluate() {System.out.println(反馈评分);}public final void process() {this.takeNumber();this.transact();this.evaluate();}}class DrawMoney extends BankTemplateMethod {public void transact() {System.out.println(我要取款!!!);}
}class ManageMoney extends BankTemplateMethod { public void transact() {System.out.println(我要理财我这里有很多钱);}
}4.20接口
接口就是规范定义的是一组规则体现了现实世界中如果你是/要…则必须能…的思想。继承是一个是不是而接口实现则是能不能的关系。
接口的本质是契约标准规范。其中接口使用interface来定义。 JDK7及以前定义接口 只能定义全局常量和抽象方法。 全局常量 interface Flyable {// 全局常量public static final int MAX_SPEED 7900;// 省略格式的全局常量int MIN_SPEED 1;
}抽象方法 interface Flyable {// 抽象方法public abstract void fly();// 省略格式的抽象方法void stop();
}接口中不能定义构造器的意味着接口不可以实例化。 Java开发中接口通过让类去实现【implements】的方式来使用。如果实现类覆盖了接口中的所有抽象方法则此实现类就可以实例化如果实现类没有覆盖接口中所有的抽象方法则此实现类仍认为一个抽象类。 Java类可以实现多个接口。 权限修饰符 class AA extends BB implements CC, DD, EE {}接口与接口之间可以继承而且可以多继承。 接口的具体使用体现多态性。 JDK8定义接口 除了定义全局常量和抽象方法之外还可以定义静态方法、默认方法。 静态方法 public interface CompareA {//静态方法public static void method1(){System.out.println(CompareA:北京);}
}默认方法 public interface CompareA {//默认方法public default void method2(){System.out.println(CompareA上海);}// 省略的默认方法default void method3(){System.out.println(CompareA上海);}
}接口中定义的静态方法只能通过接口来调用。 通过实现类的对象可以调用接口中的默认方法。如果实现类重写了接口中的默认方法调用是仍然调用的是重写以后的方法。 如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法那么子类在没有重写此方法的情况下默认调用的是父类中同名同参数的方法。【类优先原则】 如果实现类实现了多个接口而这多个接口中定义了同名的默认方法。这时就必须在实现类中重写此方法。 在子类(或实现类)的方法中调用父类、接口中被重写的方法。 方法名(); // 调用自己定义的重写方法
super.方法名(); // 调用的是父类中声明的方法
接口名.super.方法名(); // 调用接口中的默认方法4.21内部类
Java中允许将一个类A声明在另一个类B中则类A就是内部类类B称为外部类。
内部类的分类成员内部类【静态、非静态】、局部内部类【方法内、代码块内、构造器内】
class Person{//静态成员内部类static class Dog{}//非静态成员内部类class Bird{}//局部内部类public void method(){class AA{}}{class BB{}}public Person(){class CC{}}
}内部类的使用 作为外部类的成员 调用外部类的结构。可以被static修饰。可以被4种不同的权限修饰。 作为一个类 类内可以定义属性、方法、构造器等。可以被final修饰表示此类不能被继承。反之则表示可以被继承。可以被abstract修饰。 如何实例化成员内部类的对象 // 静态成员内部类
外部类名.内部类名 变量名 new 外部类名.内部类名();// 非静态成员内部类
外部类名 外部类变量名 new 外部类名();
外部类名.内部类名 内部类变量名 外部类变量名.new 内部类名();如何在成员内部类中区分调用外部类的结构 public class InnerClassTest {public static void main(String[] args) {Person p new Person();Person.Bird bird p.new Bird();bird.display(黄鹂);}
}class Person {String name 小明;class Bird{String name 杜鹃;public void display(String name) {System.out.println(name); // 方法的形参System.out.println(this.name); // 内部类的属性System.out.println(Person.this.name); // 外部类的属性}}
}