1.方法
目前所有的方法定义为public static, 加有static的方法,调用的时候必须采用“类名.”的方式调用
方法就是一段代码片段,这个片段可以完成特定的功能,并且可以重复利用
2.定义方法的语法
[方法的修饰符列表] 方法的返回值类型 方法名(方法的形式参数列表){
java语句;
}
(1)[方法的修饰符列表]是可选项,现在暂时写成public static
(2)方法的返回值类型,可以是java语言中的任意一种类型
(3)如果没有返回值,那么定义方法的时候返回值类型写void
(4)方法名只要是合法的标识符即可
(5)方法的形式参数列表,可以有参数也可以没有,如果有多个变量用“逗号”隔开
(6)如果一个方法的返回值类型不是void,那么在方法体中必须先使用return语句来返回数据,return一旦执行则方法结束
3.在当前类中,调用时类名可以省略
4.方法的重载
什么时候会发生方法的重载:
(1)发生在同一个类中
(2)方法名相同
(3)参数列表不同(类型、个数、顺序)
(4)方法的重载和方法的返回值类型无关
(5)和方法的修饰符列表无关
5.在一个类中可以有多个main()方法,构成对main()方法的重载
6.方法的执行原理:方法在调用的时候,才会给该方法在内存中分配空间。方法在调用的时候,在“栈”中分配空间。
7.递归问题
(1)方法的递归调用就是方法自身调用自身
(2)递归必须要有结束条件
例:1+2+…+n的递归求和
public static int method(n){
if(n==1){
return 1;
}else{
return n + method(n-1);
}
}
8.面向过程和面向对象的区别
面向过程:存在很多因果关系,每个步骤非常紧密,当任何一步出现问题,将会影响所有的系统
面向对象:将现实世界分割成不同的单元,实现各个对象
9.面向对象的三大特性
封装、继承、多态
OOA(面对对象的分析)
OOD(面对对象的设计)
OOP(面对对象的编程)
类 = 属性 + 方法
10.类的定义
类的修饰符 class 类名 extends 父对象名称 implements 接口名称 {
类体:属性和方法组成
}
public class Student{
//属性
//学号
int id; //成员变量,是对象级别的,必须先有对象才能访问
//姓名
String name;
//性别
boolean sex;
//年龄
int age;
//住址
Stirng addr;
//方法
}
11.对象如何创建又如何使用
new新建出的对象在heap(堆)中存储, stu1在stack中保存的是内存地址,指向在heap中的对象
stu1被称为引用
java中所有new出来的数据统一被存储在堆区中,程序员无法对堆区数据直接操作,只能通过内存地址间接操作
成员变量,对象相关的,成员变量在堆中的对象存储。成员变量如果没有手动赋值,系统则默认赋值
public class OOTest01{
public static void main(String [] args){
Student stu1 = new Student(); //新建对象
//stu1该局部变量称作引用,引用中保存了对象在堆中的内存地址,通过“引用”去间接访问对象
Student stu2 = new Student();
System.out.println(stu1.id);
}
}
12.关于系统默认值
byte, short, int, long 0
float, double 0.0
boolean false
char \u0000
引用数据类型 null
13.面向对象的封装性指的是:
(1)属性私有化
(2)对外提供公开的setter and getter
set方法和get方法的方法名应该遵循规范
java编译器可以直接编译主函数所在的类,它会把相关的类自动编译
public class Customer{
private int age;
public int getAge(){ //成员方法、实例方法、非静态方法,不带static关键字。带static关键字的方法必须用(类名.方法)的方式访问
return age; //成员方法必须使用(引用.方法)的方式访问
}
public void setAge(int _age){ //赋值
//安全控制
if(_age < 0 || _age > 100){
System.out.println("年龄不合法");
return;
}
age = _age;
}
}
private修饰的数据只能在本类中访问
对外提供两个公开的方法,
14.构造函数(构造方法、构造器)
(1)构造方法
[修饰符列表] 构造方法名(形式参数列表){
方法体;
}
(2)构造方法的方法名必须和类名一致
(3)作用
第一、创建对象
第二、初始化成员变量
(4)如何调用?
new 构造方法名(实参);在堆中开辟空间存储对象
(5)如果一个类没有提供人格构造方法,系统默认提供无参数的构造方法
如果手动提供了构造方法,系统不会提供任何构造方法
(6)构造方法可以重载
(7)成员变量到底什么时候赋值:只有在调用构造方法时才会给成员变量赋值
(8)构造方法不具有任何的返回值类型
15.引用传递
(1)传递的数据是基本数据类型
(2)传递的数据是引用数据类型
16.this关键字
(1)this是什么?
this是一个引用类型(c++中this是一个指针),保存了内存地址,在堆中每一个java对象上都有this,this保存内存地址指向自身
this指的就是当前对象,this可以用来区分成员变量和局部变量
(2)this能用在哪些地方?
第一:用在成员方法中
第二:用在构造方法中
语法: this(实参)
通过一个构造方法去调用另一个构造方法
目的:代码重用
this(实参)必须出现在代码的第一行
例:
MyDate(){
this(1970,1,1);
}
MyDate(int _year, int _month, int _day){
year = _year;
month = _month’
day = _day;
}
(3)this不能用在静态方法中
第一、静态方法的执行根本不需要java对象的存在。直接使用类名.的方式访问
在Java中同类中的静态方法能否调用类成员变量?为什么?
不行,因为java中静态的东西是类级别的,也就是说用类名就可访问,也可以用任何对象名访问,无论以哪种形式访问的都是同一个东西。
而一般我们所说的成员变量,是指对象级别的,也就是说每一个对象所拥有的成员变量都是独立的不同的变量,是属于对象自己拥有的。
相对于来说访问范围,无疑是静态的更大,静态的可以被任何对象所访问且是同一个,而成员变量是每个对象各自拥有的。
那么,为什么“静态方法不能调用类成员变量”,因为要想访问成员变量你必须有个“已经实例化好的对象”,除非你在静态方法里创建一个当前类的实例对象,
否则你是无法直接调用成员变量的,因为它不知道这个成员变量属于哪个实例对象的。
而在成员方法里,所有属于成员的变量、方法已经可以确定是同一个对象的,并且可以用this表示当前对象。
https://blog.csdn.net/zhaomengszu/article/details/79371070
17.static关键字
(1)static修饰的变量叫做“静态变量”
(2)static修饰的方法叫做“静态方法”
一般情况下工具类中方法大部分都是静态方法
静态方法不需要创建对象就可以使用
(3)static还可以定义静态语句块
静态语句块:static定义的静态语句块在类加载阶段执行,并且只执行一次,自上而下的顺序执行
public class StaticTest01{
static{
System.out.println(“1”);
}
public static void main(String[] args){
}
}
会打印出1
public class StaticTest03{
//成员方法
//成员方法必须使用“引用.”调用
public void m1(){
}
//静态方法
//可以使用“类名.”方式调用
//静态方法中不能直接访问非静态数据
//静态方法中不能使用this
public static void m2(){
}
public static void main(String[] args){
StaticTest03 st = new StaticTest03;
st.m1();
m2();
//静态的方法按照正规的方式访问:“类名.”
//静态的方法也可以通过“引用.”访问
st.m2(); //编译阶段检查出st是StaticTest03类型,编译通过,运行的时候仍然使用静态的方法按照正规的方式访问:“类名.”
//正确,不会报空指针异常,因为m2是静态的方法不是成员
StaticTest03 s = null;
s.m2();
}
}
18.实例语句块
在每一次调用构造方法之前执行一次。实力语句块执行顺序也是自上至下
19.静态变量
变量分类:
(1)局部变量
(2)成员变量(实例变量、非静态变量)
(3)静态变量(方法区)
静态变量被存储在方法区,所有java对象共享这一份
什么时候声明成静态变量:如果这个属性所有的对象都有,并且这个属性的值是相同的
成员变量:创建java对象的时候初始化
静态变量:在类加载阶段赋值,并且只赋值一次
20.关于代码的顺序:只有static的语句要遵循顺序
21.单例模式初步
单例模式是23种设计模式中最简单的设计模式
为了保证JVM中一个类型的java对象永远只有一个。为了节省内存的开销
(==两边如果是基本数据类型,则比较大小,如果是引用数据类型,则比较的是内存地址)
/*
实现单例模式
*/
//饱汉式
public class Singleton(){
//静态变量
private static Singleton s;
//将构造方法私有化
private Singleton(){}
//对外提供一个公开获取Singleton对象的方法
public static Singleton getInstance(){
if(s==null){
s = new Singleton();
}
return s;
}
}
//饿汉式
public class Customer{
private static Customer c = new Customer();
private Customer(){}
public static Customer getInstance(){
return c;
}
}
单例模式要领:
(1)构造方法私有化
(2)对外提供一个公开的静态的获取当前类型对象的方法
(3)提供一个当前类型的静态变量
22.继承
引入类继承最基本的作用是代码重用
最重要的作用:方法重写
语法:
[修饰符列表] class 子类名 extends 父类名{
类体;
}
java语言中,类和类之间只支持单继承。
一个类如果没有显式继承其他类,则默认继承Object,Object是SUN提供的根类
java语言中子类继承父类,会将父类中所有数据全部继承,包括私有的也能继承过来,但是在子类中无法直接访问父类中私有的数据,
但是可以间接访问
注意:构造方法无法被子类继承!
public class Time{
}
//MyDate除了继承Time以外,还间接继承了Object
public class MyDate extends Time{
}
23.方法的覆盖(Override)
(1)什么时候方法要进行重写?
如果父类中的方法已经无法满足当前子类中的业务需求,需要重写
(2)子类如果重写父类中的方法后,子类一定调用的是重写后的方法
(3)什么时候下会发生方法的覆盖?
第一:发生在具有继承关系的两个类之间
第二:必须具有相同的方法名、相同的返回值类型、相同的参数列表
第三:重写的方法不能比被重写的方法拥有更低的访问权限
第四:重写的方法不能比被重写的方法抛出更宽泛的异常(异常机制再讲)
第五:私有的方法不能被覆盖
第六:构造方法无法被覆盖,因为构造方法无法被继承
第七:静态的方法不存在覆盖
第八:覆盖指的是成员方法,和成员变量无关!!!
public class Test01{
public static void main(String[] args){
Cat c = new Cat();
c.move();
}
}
class Animal{
public void move(){
System.out.println(“动物在移动!”);
}
}
class Cat extends Animal{
public void move(){
System.out.println(“猫在走猫步!”);
}
}
24.多态
关于java语言中的向上转型和向下转型
(1)向上转型(upcasting):子—>父
(2)向下转型(downcasting):父—>子
注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系
public class Test02{
public static void main(Stirng[] args){
//向上转型又被称作自动类型转换
//父类型的引用指向子类型对象
//程序编译阶段只知道a1是一个Animal类型
//程序在运行的时候堆中的实际对象是Cat类型
Animal a1 = new Cat();
//程序在编译阶段a1被编译器看作Animal类型
//所以程序在编译阶段a1引用绑定的是Animal类中的eat方法(静态绑定)
//程序在运行的时候堆中的对象实际上是Cat类型,而Cat已经重写了eat方法
//所以程序在运行阶段对象的绑定的方法是Cat中的eat方法(动态绑定)
a1.eat(); //猫吃鱼
//向下转型,强制类型转换
Animal a2 = new Cat();
//直接a2.move()方法会报错,不能通过编译,要执行move方法,怎么做?
//只能强制类型转换
Cat c1 = (Cat)a2;
c1.move();
//判断以下程序运行时会出什么问题?
//Animal a3 = new Dog();
//强制类型转换
//Cat c2 = (Cat)a3; //编译没有问题,运行出现java.lang.ClassCastExpection
//在做强制类型转换的时候程序是存在风险的
//为了避免ClassCastExpection的发生,java引入了instanceof
/*
用法:
1.instanceof 运算符的运算结果是boolean类型
2.(引用 instanceof 类型)---> true/false
/*
Animal a3 = new Dog();
//推荐:在做向下转型的时候要使用instanceof运算符判断,避免ClassCastExpection
if(a3 instanceof Cat){
Cat c2 = (Cat)a3;
}
}
}
public class Cat extends Animal{
public void eat(){
System.out.println(“猫吃鱼”)
}
//cat特有的方法
public void move(){
System.out.println(“猫在走猫步!”);
}
}
public class Dog extends Animal{
public void eat(){
System.out.println(“狗啃骨头”)
}
}
25.多态的优点
(1)使用多态可以使代码的耦合度降低
(2)项目的扩展能力增强
/*
模拟主人
*/
public class Person{
//喂养
public void feed(Dog d){
d.eat();
}
//因为用户的业务改变了,所以软件要升级
public void feed(Cat c){
c.eat();
}
//以上的代码得出,Person的扩展能力太差
//尽量不要面向具体编程,面向父类型、面向抽象编程
}
/*
模拟宠物
*/
public class Dog{
public void eat(){
System.out.println(“狗吃东西!”);
}
}
public class Cat{
public void eat(){
System.out.println(“猫吃东西!”);
}
}
public class Test{
public static void main(String[] args){
Person zhangsan = new Person();
Dog d = new Dog();
zhangsan.feed(d);
}
}
public class Animal{
public void eat(){}
}
public class Dog extends Animal{
public void eat(){
System.out.println(“狗吃东西!”);
}
}
public class Cat extends Animal{
public void eat(){
System.out.println(“猫吃东西!”);
}
}
public class Person{
public void feed(Animal a){
a.eat();
}
}
26.私有的方法无法被覆盖
class A{
private void m1(){
System.out.println(“A’m1 method invoke!”);
}
public static void main(String[] args){
//多态
A a = new B();
a.m1(); //编译运行通过,A'm1 method invoke!
}
}
class B extends A{
//尝试重写父类私有的方法
public void m1(){
System.out.println(“B’m1 method invoke!”);
}
}
27.静态的方法不存在覆盖,因为静态方法执行和对象无关
class A{
public static void m1(){
System.out.println(“A’m1 method invoke!”);
}
}
class B extends A{
//尝试重写父类的静态方法
public static void m1(){
System.out.println(“B’m1 method invoke!”);
}
}
public class Test03{
public static void main(String[] args){
A a = new B();
a.m1(); //A’m1 method invoke!
}
}
28.super关键字
(1)super不是引用类型(与this不同),super存储的不是内存地址,super指向的不是父类对象
(2)super代表的是当前子类对象中的父类型特征
(3)什么时候使用super?
子类和父类中都有某个数据,例如,子类和父类中都有name这个属性,
如果在子类中要访问父类的name属性,需要使用super
(4)super可以用在什么地方?
第一:成员方法
第二:构造方法
例一:
public class Employee{
String name = “zhangsan”;
public void work(){
System.out.println(“员工在工作!”);
}
}
public class Manager extends Employee{
String name = “lisi”;
public void work(){
System.out.println(“经理在工作!”);
}
public void m1(){
this.work(); //员工在工作!
super.work(); //经理在工作!
System.out.println(name);
System.out.println(super.name);
}
/*
public static void m1(){
System.out.println(super.name) //错误,super用在成员方法中,static不需要成员
}
*/
}
public class Test01{
public static void main(String[] args){
Manager m = new Manager();
m.m1();
}
}
例二:
//账户
public class Account{
private String actno;
private double balance;
public Account(){
System.out.println("Account的无参数构造方法执行")
}
public Account(String actno, double balance){
this.actno = actno;
this.balance = balance;
}
public void setActmo(String actno){
this.actno = actno;
}
public String getActno(){
return actno;
}
public void setBalance(String balance){
this.balance = balance;
}
public String getBalance(){
return balance;
}
}
public class DebitAccount extends Account{
private double debit;
public DebitAccount(){}
//有参数的构造方法
public DebitAccount(String actno, double balance, double debit){
/* 错误,这些属性在父类中私有,无法直接访问
this.actno = actno;
this.balance = balance;
*/
super(actno, balance);
this.debit = debit;
}
public void setDebit(double debit){
this.debit = debit;
}
public String getDebit(){
return debit;
}
}
public class Test02{
public static void main(String[] args){
DebitAccount da = new DebitAccount(); //Account的无参数构造方法执行
}
}
super关键字用在构造方法中:
语法: super(实参);
作用:通过子类的构造方法区调用父类的构造方法
语法规则:一个构造方法第一行如果没有this(…),也没有显示调用super(…),系统会默认调用super(),调用父类中的无参数构造方法;
public DebitAccount(){super(“001”, 1000.0);} //不会输出Account的无参数构造方法执行
super(…);的调用只能是放在构造函数的第一行,和this(…);相同,因此不能共存
作用:给当前子类对象的父类型特征赋值
super(…);调用了父类中的构造方法,但是不会创建父类对象
在java语言中只要是创建java对象,那么Object类中的无参数构造方法一定会执行
单例模式缺点:
(1)构造方法私有化,单例模式的类型无法被继承
29.final关键字
final修饰的类无法被继承
final class A{}
final修饰的方法无法被继承的子类重写
final修饰的局部变量,一旦赋值,无法改变
final修饰的成员变量必须显式的初始化
class A{
//final修饰的成员变量必须手动初始化
final int i = 100;
final int k;
A(){
k = 200; //可行,只要在系统默认赋值之前赋值即可
}
}
final修饰的成员变量一般和static联用
public static final double PI = 3.14; //称为常量,java规范要求所有的常量大写
final修饰的引用类型,该引用不可再重新指向其他的java对象。但是final修饰的引用,该引用指向的对象的属性是可以修改的。
30.抽象类
(1)如何定义抽象类
class前加上关键字abstract
(2)抽象类无法被实例化
(3)虽然抽象类没有办法实例化,但是抽象类也有构造方法,该构造方法是给子类创建对象用的
(4)抽象类中可以定义抽象方法
抽象方法中的语法:在方法的修饰符列表中添加abstract关键字,并且抽象方法应该以“;”结束,不能带有“{}”
例如:public abstract void m1();
(5)抽象类中不一定有抽象方法,但是抽象方法必须出现在抽象类中
(6)非抽象的类继承抽象类,必须将抽象类中的抽象方法覆盖,实现,重写
public abstract class A{
A(){
System.out.println(“A…”);
}
public abstract void m1();
public static void main(String[] args){
A a = new B(); //多态,输出A…,B…
}
}
class B extends A{
B(){
System.out.println(“B…”); //隐式调用super
}
public void m1(){}
}
抽象类不能被final修饰,抽象方法不能被final修饰
31.接口
接口也是一种引用类型,可以等同看作类
(1)如何定义接口,语法:
[修饰符] interface A{}
(2)接口中只能出现:常量、抽象方法
(3)接口其实是一个特殊的抽象类,特殊在接口是完全抽象的
(4)接口中没有构造方法,无法被实例化
(5)接口和接口之间可以多继承(extends)
(6)一个类可以实现多个接口(这里的”实现“可以等同看作”继承“)(implements)
(7)一个非抽象的类实现接口,需要将接口中的所有方法”实现/重写/覆盖“
public interface A{
//常量(必须用public static final修饰)
public static final String SUCCESS = “success”;
public static final double PI = 3.14;
//public static final可以省略
byte MAX_VALUE = 127;
//抽象方法(接口中所有的抽象方法都是public abstract)
public abstract void m1();
//public abstract可以省略
void m2();
}
//客户业务接口
public interface CustomerService{
//定义一个退出系统的方法
void logout();
}
//编写接口的实现类
public class CustomerServiceImpl implements CustomerService{
//对接口中的抽象方法进行实现
public void logout(){
System.out.println(“成功退出系统!”);
}
}
public class Test{
public static void main(String[] args){
CustomerService cs = new CustomerServiceImpl(); //多态
cs.logout();
}
}
接口作用:
(1)可以使项目分层,所有层都面向接口开发,开发效率提高了
(2)接口使代码和代码之间的耦合度降低,就像内存条和主板的关系,变得可插拔,可以随意切换
接口和抽象类都能完成某个功能,优先选择接口
因为接口可以多实现,多继承,并且一个类除了实现接口以外,还可以去继承其他类(保留了类的继承)
32.Object类
关于Object中的ToString方法:
目的:返回java对象的字符串表示形式
print方法后面的括号中如果是一个引用类型,会默认调用引用类型的toString方法,输出内存地址
关于Object中的equals方法:
==两边如果是引用类型,则比较内存地址,地址相同是true,否则为false
关于Object中的finalize方法:
(1)finalize方法每个java对象都有,
(2)不需要程序员调用,由系统自动调用
(3)java对象如果没有更多的引用指向它,则该java对象成为垃圾数据,等待垃圾回收器的回收,
垃圾回收器在回收这个java对象之前会自动调用该对象的finalize方法
33.关于java语言中如何比较两个字符串一致
public class Test02{
public static void main(String[], args){
String s1 = new String(“ABC”);
String s2 = new String(“ABC”);
System.out.println(s1s2); //false
System.out.println(s1.equals(s2)); //true
}
}
String已经重写了Object中的equals方法,比较的是内容
在java中比较两个字符串是否一致不能用“”,只能调用String类的equals方法
34.包和import
软件包机制:
(1)为了解决类名的命名冲突问题,在类名前加命名空间(包机制)
(2)在java中使用package语句定义包(单包、复包)
(3)package语句只能出现在.java源文件的第一行
(4)package定义的格式。通常采用公司域名倒叙方式
(5)完整的类名是带有包名的
(6)带有package语句的java源文件必须这样编译:
javac -d 生成路径 java源文件路径
(7)运行:
java com.bjpowernode.javase.day05.User
因为有了包机制,必须在最浅层目录用包名运行
package com.bjpowernode.javase.day05; //会生成很多层目录
public class User{
public static void main(String[] args){
System.out.println(“User’s main method execute!”);
}
}
package com;
//import语句可以引入其他类
//import语句只能出现在package语句之下,class定义的语句之上
import com.bjpowernode.javase.day05.User;
//import com.bjpowernode.javase.day05.*;
//java.lang;软件包下所有的类不需要手动导入,系统自动导入
import java.util.Date;
public class Test02{
public static void main(String[] args){
//classpath就是当前路径
//在当前路径下没有
User u = new User(); //编译报错
com.bjpowernode.javase.day05.User u = new com.bjpowernode.javase.day05.User();
System.out.println(u); //调用toString方法
Date t = new Date();
System.out.println(t);
}
}
35.访问控制权限
private 只能在本类中访问
public 可以在任何位置访问
protected 本类,同一个包下,不同包下不行,但是子类中可以
缺省 本类,同一个包下,不同包下不行
35.内部类
关于静态内部类
(1)静态内部类可以等同看作静态变量,可以用访问控制权限的修饰符修饰
内部类的重要作用:可以访问外部类中私有的数据
(2)静态内部类可以直接访问外部类的静态数据,无法直接访问成员
public class OuterClass{
//静态变量
private static String s1 = “A”;
//成员变量
private String s2 = “B”;
//静态方法
private static void m1(){
System.out.println(“static’s m1 method execute”);
}
//成员方法
private void m2(){
System.out.println(“m2 method execute”);
}
//静态内部类
static class InnerClass{
//定义静态方法
public static void m3(){
System.out.println(s1);
System.out.println(s2); //错误,无法在静态方法中访问成员
m1();
m2(); //错误
}
//定义成员方法
public void m4(){
System.out.println(s1);
System.out.println(s2); //错误,无法在静态方法中访问成员
m1();
m2(); //错误
}
}
//入口
public static void main(String[] args){
OuterClass.InnerClass.m3();
InnerClass inner = new OuterClass.InnerClass();
inner.m4();
}
}
关于成员内部类
(1)成员内部类可以等同看作成员变量
(2)成员内部类中不能有静态声明
(3)成员内部类可以访问外部类所有数据
public class OuterClass{
//静态变量
private static String s1 = “A”;
//成员变量
private String s2 = “B”;
//静态方法
private static void m1(){
System.out.println(“static’s m1 method execute”);
}
//成员方法
private void m2(){
System.out.println(“m2 method execute”);
}
//成员内部类
class InnerClass{
//不能定义静态方法
//public static void m3(){
//}
//定义成员方法
public void m4(){
System.out.println(s1);
System.out.println(s2);
m1();
m2();
}
}
//入口
public static void main(String[] args){
//创建外部类对象
OuterClass oc = new OuterClass();
InnerClass inner = oc.new InnerClass();
inner.m4();
}
}
关于局部内部类
(1)局部内部类等同于局部变量
重点:局部内部类在访问局部变量的时候,局部变量必须用final修饰
public class OuterClass{
public void m1(){
int i = 10;
final int i = 10;
//局部内部类
//不能用访问控制权限修饰符修饰
class InnerClass{
//public static void m2(){} //内部类不能有静态声明
public void m2(){
System.out.println(i); //错误,局部内部类访问局部变量必须具有最终类型
}
}
//调用m2
InnerClass inner = new InnerClass();
inner.m2();
}
public static void main(String[] args){
OuterClass 0c = new OuterClass();
oc.m1();
}
}
关于匿名内部类,指的是类没有名字
优点:少定义一个类
缺点:无法重复使用
public class Test{
public static void t(CustomerService cs){
cs.logout();
}
public static void main(String[] args){
//调用t方法
//t(new CustomerServiceImp1());
//使用匿名内部类的方式执行t方法
//整个new CustomerService(){}就是个匿名内部类
t(new CustomerService(){
public void logout(){
System.out.println("系统已经安全退出");
}
})
}
}
interface CustomerService{
void logout();
}
//编写一个类实现CustomerService接口
class CustomerServiceImp1 implements CustomerService{
public void logout(){
System.out.println(“系统已经安全退出”);
}
}
36.类之间的关系
(1)泛化关系,类和类之间的继承关系及接口和接口之间的继承关系
(2)实现关系,类实现接口
(3)关联关系,类与类之间的连接,一个类可以知道另一个类的属性和方法,通常使用成员变量实现
在当前类中含有其他类的引用,在当前对象中有指向其他对象的引用
(4)聚合关系,是关联关系的一种,是较强的关联关系,是整体和部分的关系
整体不依赖部分,部分也不依赖整体,整体无法决定部分的生命周期
public class ClassRoom{
//ClassRoom和List集合属于关联关系,和Student属于聚合关系
List stus;
}
(5)合成关系,和聚合关系相似,区别的地方在于:整体和部分是紧密相连的,
整体的生命周期决定部分的生命周期
(6)依赖关系,通常反映在局部变量,返回类型,形参
37.is-a(继承), is-like-a(接口和类), has-a(关联)