Java之面向对象
1. 面向对象作用
在程序开发过程中,对象.方法 或者 对象.属性,简便易操作。
2. 面向对象概念
面向对象是一种程序设计思想,在程序设计过程中体现面向对象设计思想。
3. 面向对象程序设计
- 定义类
- 通过类创建对象
- 对象.方法 或 对象.属性
4. 面向对象程序设计特点
- 封装性:将对象的属性和行为封装起来,也就是定义类时,类中具有类成员,类成员中包括属性和方法
- 继承性:节省代码易于代码维护,将子类需要的方法和属性父类有,无需编写代码直接继承即可
- 多态性:在继承的父类后有些方法自己需要重写,出现相同方法名实现不同功能,
5.类与对象
5.1 类
-
类: 类是对某一类事务的抽象描述,类中有属性,方法。
-
面向对象程序设计中最核心就是对象,创建对象必须先定义一个类,类相当于模板
-
类的定义:
class 类名{ //属性 数据类型 变量名 //方法 返回值类型 方法名(形参参类型 形参名,...){ } } class People{ int age; void speak(){ System.out.println("人会说话") } }
5.2 对象
-
对象的创建:
类名 对象名 = new 类名(形参); People people = new People();
-
对象的使用
people.age = 18; //给属性赋值 people.speak(); //调用对象的方法
-
创建对象时没有初始化属性,JVM会自动为成员变量进行默认初始化
-
若内存中开辟空间没有变量引用该对象时,此对象被当作垃圾自动回收释放内存
public class Test { public static void main(String[] args) { Person person = new Person(); person.say(); person = null; person.say(); } } class Person{ int age; void say() { System.out.println("我是一个人"); } }
-
对象的内存解析
5.3 成员变量与局部变量
- 相同点:
- 定义变量: 数据类型 数据名 = 变量值
- 先声明,后使用
- 都具有作用域
- 不同点
- 成员变量声明在类{}中,局部变量在方法,形参,代码块,构造器内部
- 成员变量可以使用权限修饰符 public private protect
- 成员变量具有默认构造参数,局部变量没有,在代码块,方法中的形参必须有初始值。
- 成员变量加载到堆空间(非static),局部变量加载到栈空间。
6.retutn关键字作用
- 适用范围:在方法体中使用
- 作用:
- 结束方法
- 针对于有返回值类型的方法,使用return 返回数据
- return 关键字后面不可以声明执行语句。
7.成员方法使用
- 方法体中可以调用属性和成员方法
- 方法中部可以定义方法
8.对象数组的内存解析
9.匿名对象
没有引用创建的对象
new 类名()
10.方法重载
在一个类中,方法名相同,返回值类型,形参类型和个数不全都相同
11.可变形式参数
11.1语法
//数据类型 ... 变量名
public class MethodArgsTest{
void show(int max){
System.out.println(max);
}
void show(String string){
System.out.println(string);
}
void show(String ... string){
System.out.println(string)
}
}
11.2注意:
-
当参数为一个字符串时,下面两个方法重载,优先匹配第一个方法
void show(String string) void show(String ... string)
-
方法形参最多声明一个可变形参,必须在形参列表的末尾
-
可变形参,传入参数个数可以是多个
-
下面两个函数不构成重载函数,两个函数是相同的
void show(String[] string) void show(String ... string)
12.变量的赋值
-
如果变量是基本数据类型,此时赋值的是变量所保存的数据值
int a = 10; int b = a;
-
如果变量是引用数据类型,此时赋值的是变量所保存的数据地址值
int[] arr1 = new int[10]; int[] arr2 = arr1;
13.方法形参的传递机制
13.1 形参:方法定义时,声明小括号内的参数
实参:方法调用时,实际传递给形参的数据
-
2 值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实储存的数据值
如果参数是引用数据类型,此时赋值的是变量所保存的数据地址值。
14.递归方法
方法自己调用自己,必须有程序出口和返回值
/*例:求n的阶乘
n=1 1! = 1;
n>1 n! = (n-1)!*n
*/
public int fun(int n){
if(n==1)
{
return 1;
}else{
return fun(n-1)*n;
}
}
15.封装与隐藏
特点:高内聚,低耦合
-
封装性的体现需要配合修饰符
-
java归定的四种权修饰符:private,缺省,protected,public
-
四种权限修饰符放类成员定义前,用来限定对象对该成员的访问权限
-
权限修饰符可以修饰类的内部结构:属性方法构造器内部类
-
class只能被public和缺省修饰
-
封装类具体体现
- 将属性私有化,创建get(获取)set(设置)方法,赋值和获取属性值,可有对属性值加限制条件
- 将方法私有化,私有化方法只能被类内的方法调用
-
类内部的属性,可以被方法调用
-
同包不同类,通过对象不可以调用私有属性和方法
-
不同包,通过对象私有,缺省不可以被调用
-
不同工程不能调用
-
限制访问权限,也就是暴露范围的的大小
16.构造器
16.1 构造器的作用
- 创建对象
- 初始化对象信息
16.2 构造器说明
-
一个类中至少有一个构造器
-
自己定义了构造器,系统不再提供无参构造器
-
一个类可以有多个重载构造器
-
创建的语法
权限修饰名 类名(形参列表){ }
17.属性赋值
- 默认初始化
- 显式初始化
- 构造器中赋值
- 对象.方法,对象.属性 赋值
- 先后顺序: 1 ,2,3,4
- 1.2.3只执行一次,4可执行多次
18.JavaBean
-
javabean是一种java语言写成的可重用组件
-
Javabean具有一下特点:
- 类是公共的
- 有一个无参的公共的构造器
- 有属性,且有对应的get,set方法
19.this关键字
-
this理解为:当前对象或当前正在创建的对象
-
this可以修饰属性,方法,构造器
-
修饰属性,方法可以省略this,当属性名和形参名相同时不可以省略
class Person{ public int age; public Sting name; public Person(){ Say(); //调用方法,省略this System.out.println("我是一个人"); } public Person(int age,String name){ this.age = age; this.name = name; //无法省略this } public void SetName(String n){ name = n; //省略this. } public void Say(){ System.out.println("人会说话 } }
-
this调用构造器
- 语法
// this(形参表); public Person(){ System.out.println("我是一个人"); } public Person(String name){ this(); //调用无参构造 System。out。println("我叫" + name); } public Person(String name,int age){ this(name); System.out.println("今年" + age + "岁"); }
- 注意
- 一个构造器只能调用一次构造器
- 构造器调用必须放在首行
- 有n个构造器,最多有n-1次构造器调用
- 构造器之间不能相互调用
-
20.package关键字
package的使用:
- 项目中管理类
- 源文件中要声明它所属的包
- 包名命名都是小写用.隔开,没.一次代表一层文件目录
java常用包:java.lang java.net java.io java.util java.text java.sql java.awt
21.MVC 设计模式
是一种程序设计方式,创建包的一种方式,分为视图模型层(v),控制器层(c),数据模型层(m)
- 数据模型层(model):主要处理数据,数据对象进行封装,数据库进行操作
- 控制层(controller):处理业务逻辑
- 视图层(view):显示数据
22.import关键字使用
-
在不同包下的类或者接口需要在类或者接口使用,使用import导入
-
”xxx.*“表示可以导入xxx包下的所有类或者接口,如果xxx包下还有包,里面的包不被默认导入
-
使用java.lang包下的类和接口可以省略
-
使用类名相同的类,其中一个需要以全类名的方式显示
import com.nan.pojo.Person; Person person1 = new Person(); com.nan.entity.Person person2 = new com.nan.entity.Person();
-
import static:导入指定类的接口中的静态结构,属性或者方法
import static com.nan.pojo.Person.*; import static java.lang.System.*; out.println();
23.继承
-
继承:提高代码的复用性,易于代码维护,得到父类的属性和方法。
-
语法
public class 子类名 extends 父类名{ }
-
子类继承父类构造器没有继承需要子类重新定义
-
子类是父类的拓展
23.1 java中继承的规定
- 只能单继承,一个子类只能继承一个父类
- 父类可以被多个子类继承
- 子类直接继承的父类成为直接父类,间接继承的父类称为间接父类
- 如果没有显示继承一个父类,系统默认继承java.lang.object类
- 所有的类直接或间接的继承了object类
24.方法重写
-
重写:对父类方法的覆盖,通过子类对象调用父类中被重写的函数,实际执行的是子类重写后的函数
-
java重写的规定
方法声明
权限修饰符 返回值类型 方法名(形参列表) throw 异常类型{ 方法体 }
- 子类的方法名和形参列表必须和父类相同
- 子类返回值类型和父类返回值类型相同,如果父类返回值类型有子类,则子类的返回值类型可以为他的子类
- 子类的异常类型是父类异常类型的子类或者与父类相同
- 父类具有static的方法,子类可以有同名同参数的方法且必须有static,子类的该方法不能称作方法重写
- 子类的方法权限修饰符与父类相同或者比父类权限范围更大的权限修饰符
- 父类为private修饰的方法子类不能重写
25.super关键字
作用:在子类调用父类的属性,方法,构造器
25.1 super调用父类属性和方法
- 当子类的属性和方法没有与父类重名时可以省略super.,则默认掉用父类的方法和属性
- super.方法如果直接父类没有就会找间接父类的方法
25.2 super调用父类构造器
- 可以在子类通过super(形参列表)调用父类构造器
- super调用父类构造器必须放在子类构造器首行,与this调用的构造器,在一个构造器只能存在一个,有且只有一个
- 若子类构造器没有显示声明this,super构造器调用,系统默认调用父类的无参构造super();
26.子类对象实例化全过程
26.1 从结果上看:
- 子类继承父类后,就获取了父类中声明的属性或者方法
- 创建子类对象,在堆空间中,就会加载所有父类中声明的属性
26.2 从过程上看
通过子类创建对象时,子类的构造器会调用父类的默认构造器,直到调用到java.lang.object,构造方法完成,对象创建成功,在次期间只子类一个对象,调用多次构造器。
27.多态性
-
多态:由于参数类型不同而导致执行效果各异的现象就是多态,继承是多态得以实现的基础
-
java中实现多态:父类引用子类对象,父类类型变量调用自己被子类重写的方法,会得到不同结果,方法被重写后才具有多态性。
-
属性不具有多态性
public class Test01 { public static void main(String[] args) { Anmal anmal = new Dog(); anmal.shout(); System.out.println(anmal.age); } } class Anmal { int age=1; public void shout() { System.out.println("动物会叫"); } } class Dog extends Anmal { int age=2; String name; public void shout() { System.out.println("狗会叫"); } }
-
多态的使用:虚拟方法调用
- 编译期只能调用父类中声明的方法,运行期间,调用的是子类重写父类的方法
-
多态是运行时行为
public class Test01 { public static Anmal getInstance(int key) { switch (key) { case 0: return new Anmal(); case 1: return new Dog(); case 2: return new Cat(); default: return new Sheep(); } } public static void main(String[] args) { int key = new Random().nextInt(3); System.out.println(key); Anmal anmal = getInstance(key); anmal.shout(); } } class Anmal { public void shout() { System.out.println("动物会叫"); } } class Dog extends Anmal { public void shout() { System.out.println("狗会叫"); } } class Cat extends Anmal{ public void shout() { System.out.println("猫会叫"); } } class Sheep extends Anmal{ public void shout() { System.out.println("羊会叫"); } }
-
虚拟方法
子类重写父类方法,在多态情况下,此时父类的方法就叫做虚拟方法。
-
动态绑定:编译时对象是父类对象,运行时确定方法调用
28.重载与重写
- 方法重载:允许有方法名相同,参数列表和返回值不全都相同
- 方法重载在编译器就确定了,称为早绑定,静态绑定
- 子类和父类同名函数不同参数或者返回值也称作方法重载
- 多态是一种运行才时能确定调用哪个方法,称为晚绑定,动态绑定
- 如果不是晚绑定,就不是多态
29.向下转型
-
向下转型:将父类引用子类对象转换为子类引用对象
-
语法:
// 类A 类名a = (类A) 类名b; //例一 Person person = new Student(); Student student = (Student) person; //例二 Object obj = new Woman(); Person p = (Person) obj;
-
向下转型作用:父类的引用不能调用子类特有的属性和方法,通过向下转型,此时可以调用子类特有的方法和属性
-
instanceof作用:判断b引用的对象类是否为A类或者A类的父类,返回值为true或false,为true可以转型,为false不能转型
-
instanceof语法
if(a instanceof A){ 方法体 }
30. equals()和"=="区别
- “==”
- 是运算符
- 在基本数据类型中,比较的是两个数据是否相同
- 在引用数据类型,比较的是两个引用对象的地址值
- “equals()方法的使用”
- 是一个方法
- 只适用与引用数据类型
- 重写之前比较两个对象的地址值是否相同与“==”作用相同,重写之后一般用来比较两个对象的“实体内容”是否相同
- String,Date,File,包装类都重写了Object类中的equals()方法
31. toString()方法
toString()方法是在Object类中定义,其返回值是String类型,返回类名和它的引用地址
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
重写toString()之后作用是将引用数据类型的值准换为字符串
32. Java中JUnit单元测试
32.1 步骤:
- 创建public 和具有无参构造器的java类,进行单元测试
- 测试方法:类中声明权限为public和没有返回值类型的方法,不具有形参
- 测试方法上需要声明@Test,测试方法声明完成
- 在方法中写方法体
- 写完代码后,运行即可
33.包装类
-
包装类:针对八大基本数据类型定义了相应的引用数据类型,,使得基本数据类型具有类的特征,java真正才是面象对象
-
基本数据类型,包装类,String相互转换
-
基本数据类型—>包装类;调用包装类构造器
//包装类 对象 = new 包装类名(基本数据类型); Integer integer = new Integer("132"); Integer integer =new Integer(13);
-
包装类转换为基本数据类型
- 方式一
//对象名.xxxValue(); @Test public void test_02() { Integer integer = new Integer(20); int i = integer.intValue(); System.out.println(i); }
-
方式二:自动装箱拆箱
int a = 10; Integer integer = a; //自动装箱 System.out.println(integer.toString()); int b = integer + 10; //自动拆箱 System.out.println(b);
-
基本数据类型,包装类转为String
-
方式一:加空字符串
int a = 10; String string = a + "1"; System.out.println(string); //结果101
-
方式二:调用 String.valueOf()方法
int a = 10; String string = String.valueOf(a) + 1; System.out.println(string);
-
方式三:调用toString()方法
Integer a = Integer(10); String string = a.toString();
-
-
String转换为包装类和基本数据类型
-
方式一:调用parseXxx()方法
String string = new String("123"); int a = Integer.parseInt(string);
-
-
34.static关键字的使用
-
static:静态的
-
static可以修饰:属性,方法,代码块,内部类
-
使用static修饰属性:
3.1 被static修饰的变量称为静态变量或类变量,没有static修饰变量为非静态变量或实例变量
3.2 对象的创建会独立有一套类中的非静态变量,静态变量不是独立具有的是所有对象共享的
3.3 静态变量随着类的加载,可以通过类名直接调用静态变量
3.4 类只加载一次,静态变量在内存也只会存在一份,存在方法区或者静态域中
3.5 静态变量的加载早于对象的创建
-
类变量和实例变量内存解析
-
使用static修饰方法(从生命周期的角度去理解)
5.1 静态方法是随着类加载的
5.2 类可以调用静态方法,对象可以调用静态方法和非静态方法
5.3 静态方法只能调用静态属性和静态方法
5.4 非静态方法可以调用静态和非静态属性和方法
-
属性是可以被多个对象共享的,不会随着对象的不同而改变,一般设置为静态变量
-
操作静态属性的方法,通常设置为static
-
工具类中的方法,一般声明为static
35.单例设计模式
设计模式:大量实践中总结和理论化之后优选的代码结构,编程风格,以及解决问题的思考方式,“套路”。
单例设计模式:就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在虚拟机中只产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样就不在类外部使用new产生对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能刚问类中的静态成员变量,所以,指向类内部产生的的该类对象的变量也必须定义成静态的。
-
饿汉式:
class Person{ private Person() { System.out.println("创建了一个唯一对象"); } private static Person person = new Person(); public static Person setPerson() { return person; } }
-
懒汉式:
class Person{ private Person() { System.out.println("创建了一个唯一对象"); } private static Person person = null; public static Person setPerson() { if(person==null) { person = new Person(); } return person; } }
-
懒汉式和饿汉式区别:
- 懒汉式较比饿汉式更省空间
- 饿汉式是线程安全的,懒汉式线程不安全
-
软件系统中某个类只需要一个对象实例,就可以使用单例设计模式
36.main()方法的使用说明
-
mian()方法作为程序的入口
-
mian()方法也是一种普通的静态方法
-
main()方法可以作为我们与控制台交互的方式
-
java中一个程序可以有多个main方法
public class Test01 { public static void main(String[] args) { System.out.println("mian1"); A.main(new String[20]); } } class A{ public static void main(String[] args) { for(int i =0;i<args.length;i++) { args[i] = "args[" + i + "]=" + i; } for(int i =0;i<args.length;i++) { System.out.println(args[i]); } } }
37.代码块
- 代码块:在类中用{}括起来的代码,叫做代码块,代码块只能用static修饰,没有权限修饰符,返回值类型和方法名
- 代码块的作用:用来初始化类,对象
- 静态代码块:用static修饰的代码块
- 内部可以有输出语句
- 随着类的加载而执行
- 有多个静态代码块,按声明先后顺序执行
- 静态代码块先于非静态代码块执行
- 静态代码块只能调用static所修饰的方法属性代码块
- 非静态代码块
- 内部可以有输出语句
- 随着对象的创建运行,对象创建一次非静态代码块运行一次
- 可以在对象创建的时候对属性值进行赋值,和方法调用
- 类中有多个非静态代码块,按照声明先后顺序执行
- 非静态代码块可以调用static修饰和没有static修饰的方法属性代码块
- 对象可以赋值的位置
- 相比较之前多了一种:在代码中对属性赋值,共5中
- 属性赋值顺序
- 1 默认初始化 2 显式初始化 3 构造器初始化 4 通过对象初始化 5 代码块初始化
- 顺序: 1,2/5,3,4 方式2和5声明在前的先赋值
38. final关键字
-
final:最终的
-
final作用:
- final可以修饰类,方法,变量
- final修饰类,此类不可以被继承
- final修饰方法,此方法不可以被重写
- final修饰变量,变量的值不可以修改
-
final修饰的变量赋值方式
-
方式一:定义时候直接赋值
final int a = 10;
一般适用于所有对象属性值值相同且只有赋值操作
-
方式二:变量是类中的属性时,可以通过代码块赋值
{ a = 10; }
一般适用所有对象的属性值相同且有其他额外操作
-
方式三: 变量是类中的属性时,可以通过构造器初始化
public A(int n){ a = n; }
对象的属性值不同且有其他额外操作
-
-
final修饰局部变量:
- 局部变量的值不可以修改
- 当final修饰形参的时候,方法体中只能用该值不能修改该值
-
static final 可以修饰方法和属性
- 修饰方法:全局方法,不可以被重写
- 修饰属性: 全局属性,常量
39.抽象
-
abstract:抽象的
-
abstract可以用来修饰的结构:类,方法
-
abstract修饰类:抽象类
- 此类不可以实例化对象
- 具有构造器,子类需要调用父类构造器
- 开发中会提供子类,让子类对象实例化完成相关操作
-
abstract修饰方法:抽象方法
- 抽象方法没有函数体,只有函数声明,不能被对象调用
- 有抽象方法的类一定是抽象类,要用abstract
- 子类继承抽象类,若没有重写抽象方法,则子类时抽象类
-
abstract使用上的注意点:
- abstract不能用来修饰:属性,构造器等结构
- abstract不能用来修饰私有方法,私有方法不能被重写
- 静态方法不能被重写,不能成为抽象方法
- final修饰的方法不能被重写,不能成为抽象方法
- final类不能被继承,abstract修饰后此类无法实例对象
-
抽象类的匿名子类:new 对象的时候重写抽象类的方法,相当于继承抽象类并且重写了抽象方法,此时创建的对象具有的方法是自己特有的
A a = new A() { @Override public void sum() { // TODO Auto-generated method stub System.out.println(123); } @Override public void cut() { // TODO Auto-generated method stub System.out.println(234); } };
40. 模版方法设计模式
-
抽象类体现的就是一种模板模式设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展,改造,但子类总体上会保留抽象类的行为方式。
-
在软件开发中实现一个算法时,整体步骤很固定,通用,这些步骤已经在父类中写好了,但是默写部分易变,易变的部分可以抽象出来,供不同子类实现,这就是一种模板设计模式。
-
举例
-
abstract class A{ public long spendTime(int n) { long start = System.currentTimeMillis(); fun(n); long end = System.currentTimeMillis(); return end-start; } public abstract int fun(int n); } class B extends A{ @Override public int fun(int n) { // TODO Auto-generated method stub for(int i =0;i<n;i++) { System.out.println(i); } return 1; } }
-
41. 接口的使用
-
接口使用interface来定义
-
java中接口和类是并列的两个结构
-
如何定义接口,定义接口中的成员
- JDK7之前:只能定义全局常量和抽象方法
- 全局常量:public static final,书写时可以省略
- 抽象方法: public abstract的,书写可以省略
- JDK8:除了定义全局常量和抽象方法,还可以定义静态方法,默认方法
- JDK7之前:只能定义全局常量和抽象方法
-
接口中不能有构造器,接口不可以被实例化
-
Java开发中,接口通过类实现接口,如果实现了接口中的所有抽象方法,此类可以实例化,否则子类称为抽象类
-
java可以实现多个接口,弥补了java单继承局限性
public final class AA entends BB implements java.io.Serializable,Comparable<String>,CharSequence{ //先继承后实现接口 }
-
接口可以多继承
interface AA{ } interface BB{ } interface CC extends AA,BB{ }
-
接口的具体使用,体现多态性
-
接口,实际上可以看作一种规范
-
匿名实现类
USB usb = new USB() { @Override public void start() { // TODO Auto-generated method stub System.out.println("一个插口"); } @Override public void stop() { // TODO Auto-generated method stub System.out.println("一个插口"); } };
42. 代理模式
-
概述:代理模式时java开发中使用较多的一种设计模式,代理设计就是为了其他对象提供一种代理以控制对这个对象的访问。
-
代理类和被代理类都实现相同的接口
-
例一
public static void main(String[] args) { Server server = new Server(); ProxyServer proxyServer = new ProxyServer(server); proxyServer.browse(); } interface NetWork{ public void browse(); } //被代理类 class Server implements NetWork{ @Override public void browse() { // TODO Auto-generated method stub System.out.println("真实的服务器访问网络"); } } //代理类 class ProxyServer implements NetWork{ private NetWork netWork; public ProxyServer(NetWork netWork) { this.netWork = netWork; } public void check() { System.out.println("联网之前的检查工作"); } @Override public void browse() { // TODO Auto-generated method stub check(); netWork.browse(); } }
-
例二
public class Test { public static void main(String[] args) { RealStar realStar = new RealStar(); Proxy proxy = new Proxy(realStar); proxy.sing(); } } //接口 interface Star{ void confer(); //面谈 void signContract(); //签合同 void bookTicket(); //订票 void sing(); //唱歌 void collectMoney(); //收钱 } //被代理类(歌手) class RealStar implements Star{ @Override public void confer() { // TODO Auto-generated method stub } @Override public void signContract() { // TODO Auto-generated method stub } @Override public void bookTicket() { // TODO Auto-generated method stub } @Override public void sing() { // TODO Auto-generated method stub System.out.println("明星唱歌"); } @Override public void collectMoney() { // TODO Auto-generated method stub } } //代理类(经纪人) class Proxy implements Star{ private Star star; public Proxy(Star star) { // TODO Auto-generated constructor stub this.star = star; } @Override public void confer() { // TODO Auto-generated method stub } @Override public void signContract() { // TODO Auto-generated method stub } @Override public void bookTicket() { // TODO Auto-generated method stub } @Override public void sing() { // TODO Auto-generated method stub System.out.println("代理人处理事"); star.sing(); } @Override public void collectMoney() { // TODO Auto-generated method stub } }
43. 工厂设计模式
-
工厂设计模式:实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
//工厂方法模式 interface Car{ void run(); } class Audi implements Car{ public void run() { System.out.println("奥迪在跑"); } } class BYD implements Car{ public void run() { System.out.println("BYD在跑"); } } interface Factory { Car getCar(); } class AudiFactory implements Factory{ @Override public Audi getCar() { // TODO Auto-generated method stub return new Audi(); } } class BydFactory implements Factory{ @Override public BYD getCar() { // TODO Auto-generated method stub return new BYD(); } }
//简单工厂 interface Car{ void run(); } class Audi implements Car{ public void run() { System.out.println("奥迪在跑"); } } class BYD implements Car{ public void run() { System.out.println("BYD在跑"); } } class CarFactory{ public static Car getCar(String type) { if("奥迪".equals(type)) { return new Audi(); }else if("比亚迪".equals(type)){ return new BYD(); }else { return null; } } public static Car getAudi() { return new Audi(); } public static Car getByd() { return new BYD(); } }
//无工厂 interface Car{ void run(); } class Audi implements Car{ public void run() { System.out.println("奥迪在跑"); } } class BYD implements Car{ public void run() { System.out.println("BYD在跑"); } }
44. Java8中关于接口的改进
- Java8中可以为接口添加静态方法和默认方法
- 静态方法使用static关键字修饰,使用接口直接调用静态方法
- 默认方法用default关键字修饰,可以通过是实现类对象来调用
- 接口中定义的静态方法只能用接口调用
- 接口中定义的默认方法,实现类可以调用
- 实现类重写了默认方法,对象调用的时重写以后的方法
- 类实现接口并且继承父类,接口和父类有同名同参数的方法,类对象调用的是父类的方法
- 实现两个接口吗,两个接口有相同的同名方法,实现类必须重写该方法
- 类实现接口并且继承父类并且子类重写了方法,子类调用父类方法使用super.方法,子类调用接口的方法使用接口名.super.方法
45.内部类
-
Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
-
内部类的分类:成员内部类(静态,非静态)VS 局部内部类(方法内,代码块内,构造器内)
-
成员内部类
- 作为外部类成员
- 调用外部类的结构
- 可以被static修饰
- 可以被4中权限修饰符修饰
- 作为一个类
- 类中可以定义属性,方法,构造器
- 可以被final修饰,表示此类不能被继承
- 可以被abstract修饰
- 作为外部类成员
-
实例化成员内部类
public class Test07 { public static void main(String[] args) { AA.C c = new AA.C(); AA a = new AA(); AA.B b = a.new B(); b.say(3); } } class AA{ int m=1; int n; class B{ int m=2; public void say(int m) { System.out.println(m); System.out.println(this.m); System.out.println(AA.this.m); } } static class C{ public void say() { System.out.println("========C"); } } public void say() { System.out.println("=====A"); } }
-
在成员内部类区分调用外部类结构
-
开发中局部内部类使用
interface BB{ int bB(Object o); } public BB getBB() { //实现BB接口:局部内部类 class BBB implements BB{ @Override public int bB(Object o) { // TODO Auto-generated method stub return 0; } } return new BBB(); }