面向对象编程(知识点概括 和 一些题型)

类和对象的概念 

类是抽象的,是一种数据类型  。对象是具体的  对象实现了类的实例化

属性和方法

属性:(又称作成员变量)可以是基础数据变量,也可以是数组或者对象 ,

          属性有默认值 例如boolean类型的数据默认为false

方法:将实现的细节封装起来,提高代码的复用性,可以供其他的用户使用

重载,重写,可变参数

方法重载  -----方法名相同 ,参数列表不同,返回类型无要求

方法重写 ------方法名相同,参数列表相同,返回的类型和父类返回的类型一致,或者是父类                         返回类型的 子类型

可变参数 ------ 可变参数本质为数组,和普通的参数放在一起的时候,可变参数放最后,

构造器  --------方法名与类名相同,没有返回值,创建对象时,完成对新对象的初始化

面向对象三大特征  :封装 继承和多态

封装是把属性和方法封装在一起,数据被保护在内部,其他程序必须通过被授权的操作,才能对数据进行操作  一般使用属性私有化,然后通过get方法 和set方法来实现封装

继承可以结局代码复用,当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同 的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可

多态是指一个类中定义的属性和方法被其他类继承后,他们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义(多态的前提是两个对象存在继承关系)

super和this的比较

调用父类的某个构造器:super(参数列表)

调用本类的某个构造器:this(参数列表)

super在使用时,必须放在构造器第一行,因为this()也必须放在第一行,所以super()和this()不能共存一个构造器中

super从父类开始查找属性,从父类查找方法,

                调用父类构造器必须必须放在子类构造器首行

this先从本类中查找属性,从本类中查找方法,如果本类中没有属性和方法,再从父类中查找属性和方法 ,但不能访问父类的私有属性和方法 。调用本类构造器,必须放在构造器首行

向上转型:父类的引用指向子类的对象
公式:父类类型引用名 = new 子类类型();
Animal animal =new Cat();
Object obj =new Cat();
向下转型: 父类的引用指向当前目标类型的对象
Cat cat = (Cat)animal

一般会有一个判断条件
if (cat instanceof Animal)
Cat cat =(Cat)animal

Object类的方法

equals方法

判断两个 对象的内容是否相等 如果两个person对象的各个属性值都一样 返回true,否则返回false

class Person{
    public  String name;
    public  int age;
    public  char sex;
    //重写Object的equals方法
    public boolean equals(Object obj){
        //判断如果比较的两个对象是同一个对象,则直接返回true;
        if(this == obj){
            return  true;
        }
        //类型判断
        if(obj instanceof Person){
            //如果是Person.我们才比较,不能出现人和小狗比这样的比较
            //进行向下转型,因为需要得到obj 的各个属性
            Person p =(Person) obj;
            return this.name.equals(p.name) && this.age == p.age&& this.sex ==p.sex;}
        //如果不是Person.则直接返回false.
        return  false;
    }

hashCode方法

返回对象的哈希码值,此方法是为了提高哈希表的性能

没有搞明白

finalize方法

对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做出释放资源的操作

垃圾回收机制的调用,是由系统来决定,也可以通过system.gc()主动触发垃圾回收机制

public class Finalize_ { 
	public static void main(String[] args) { 
		Car bmw = new Car("宝马"); 
		//这时 car 对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对                
          象的 finalize 方法 
		//程序员就可以在 finalize 中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打 
          开文件..) 
		//如果程序员不重写 finalize,那么就会调用 Object 类的 finalize, 即默认处理
		//如果程序员重写了 finalize, 就可以实现自己的逻辑 
		bmw = null; 
		System.gc();//主动调用垃圾回收器 
		System.out.println("程序退出了...."); 
	} 
}
class Car { 
	private String name; 
	//属性, 资源。。 
	public Car(String name) { 
		this.name = name; 
	}
	//重写 finalize 
	@Override 
	protected void finalize() throws Throwable { 
		System.out.println("我们销毁 汽车" + name ); 
		System.out.println("释放了某些资源..."); 
	} 
}

静态成员

静态成员包括:静态属性和静态方法

1.引入原因:静态变量是同一个类所有对象共享 比如说一个学生拥有一支笔 在定义这个类的时候他就有这只笔了  不管定义的对象是什么学生 都有一只笔

2.特点:  static 类变量,在类的加载的时候就生成了 也随着类的消亡而销

3.静态属性公式:1.访问修饰符 static 数据类型 变量名;

                             2.static 访问修饰符 数据类型 变量名

4.静态方法公式:1.访问修饰符 static 数据返回类型 方法名(){}

                             2.static 访问修饰符 数据返回类型  方法名(){}

5.调用方法:类名.类变量名   类名.类方法名

注意:类方法中不允许使用和对象有关的关键字 比如说this 和super ,并且类方法中只能访问静态变量和静态方法。

代码块

引入原因:相当于另外一种构造器 可以做一些初始化操作 。如果多个构造器有重复的语句,可以抽取到初始化块中,提高代码的重用性。

特点:类加载时,或者创建对象时,隐式调用

分类:静态代码块 和普通代码块

静态代码块随着类的加载而执行,并且只会执行一次

普通代码块每创建一个对象,就会执行一次

创建一个类时的调用顺序

父类的静态代码块,静态属性,静态方法

子类的静态代码块,静态属性,静态方法

父类的普通代码块,普通属性,普通方法

父类的构造方法

子类的普通代码块,普通属性,普通方法

子类的构造方法

补充:类被加载的几种情况

1)创建对象实例时

2)创建子类对象实例,父类也会被加载

3)使用类的静态成员时

final关键字

引入原因:

1)当不希望类被继承时,可以使用final关键字

2)当不希望父类的某个方法被子类覆盖/重写时,可以使用fianl关键字修饰

3)当不希望 某个属性值被修改是,可以使用final关键字

4)当不希望某个局部变量被修改,可以使用final修饰

使用方法 

1)final修饰的属性又称常量 一般用XX_XX_XX来命名(大写)

2)final修饰的属性在定义时,必须赋初值,并且以后不能修改 ,赋值可以在以下位置之一

       1.定义时      2.在构造器中        3.在代码块

3)如果final修饰的属性是静态的,则初始化的位置只能是

        1.定义时         2.在静态代码块 不能在构造器中赋值

4)  final类不能继承 但是可以实例化对象

5)如果类不是final类,但是含有final方法,该方法不能被重写,但是可以被继承

6)final不能修饰构造方法

7) final和static往往搭配使用 效率更高,变量成为全局变量

抽象类(abstract)

引入原因:

作为父类不知道子类具体的实现的时候,使用一个抽象方法,让子类去实现具体的细节

例如:在父类为animal类,定义一个叫声的抽象方法,子类Cat实现就是喵喵喵,子类Dog实现则为汪汪汪。父类的叫声的抽象方法,子类继承必须要有具体实现

使用规范:

抽象类不能被实例化

抽象类公式: 访问修饰符 abstract 类名

抽象方法公式:访问修饰符  abstract  返回类型 方法名 (参数列表);//没有方法体

抽象类的价值更多在于设计:让子类继承并实现抽象类

abstract只能修饰类和方法 ,不能修饰属性和其他的

抽象方法不能被private ,final 和static修饰

抽象类不一定要包含抽象方法,但是包含抽象方法一定是抽象类,一个类继承了抽象类,必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类(重点)

例题:

package Abstract;

public class abstract_ {

}
abstract class Animal{
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    //思考:这里的eat方法没有意义,即父类方法不确定性问题
    // 可以将该方法设计为抽象方法
    //所谓抽象方法就是没有实现的方法,即没有方法体
    // 当一个类有abstract方法时,应该声明该类是abstract类,
    public abstract void eat();
}

接口

引入原因:

接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来

比如:你可以把手机,相机,U盘都插在usb插槽上,而不用担心那个插槽是专门插哪一个的,原因是做usb插槽的参加和做各种设备的厂家都遵守了统一的规定包括尺寸,盘线等

interface 接口名{

//属性

//方法(1.抽象方法  2,默认实现方法   3,静态方法)

}

class 类名 implements 接口{

        自己的属性

        自己的方法

        必须实现的接口的接口方法

}

接口的实现规范:

1.接口不能被实例化,一个类可以实现多个接口

2.接口中所有方法是public方法 ,接口中抽象方法,可以不用abstract去修饰

3.接口中的默认属性修饰符为 public static final

4. 抽象类实现接口可以不用实现接口方法,普通类实现接口必须实现接口的所有方法

5.接口中的属性的访问形式:接口名.属性名

6.接口不能结城其他的类,但是可以继承多个别的接口

7.接口的修饰符只能是public 和默认 这点和类的修饰符是一样的

接口和继承的区别

继承的价值主要在于:解决代码的复用性和可维护性

接口的价值主要在于:设计,设计好各种规范,让其他类去实现这些方法。

接口比继承更加灵活,继承是is -a的关系 而接口只需满足like -a的关系

例题

package com.hspedu.interface_; 

public interface DBInterface { //项目经理 
	public void connect();//连接方法 
	public void close();//关闭连接 
}

package com.hspedu.interface_; 
//A 程序 

public class MysqlDB implements DBInterface { 
	@Override 
	public void connect() { 
		System.out.println("连接 mysql");
	}
	@Override 
	public void close() { 
		System.out.println("关闭 mysql"); 
	} 
}
package com.hspedu.interface_; 
//B 程序员连接 Oracle 
public class OracleDB implements DBInterface{ 
	@Override 
	public void connect() { 
		System.out.println("连接 oracle"); 
	}
	@Override 
	public void close() { 
		System.out.println("关闭 oracle"); 
	} 
}
package com.hspedu.interface_; 
public class Interface03 { 
	public static void main(String[] args) {
		MysqlDB mysqlDB = new MysqlDB(); 
		t(mysqlDB); 
		OracleDB oracleDB = new OracleDB(); 
		t(oracleDB); 
	}
	public static void t(DBInterface db) { 
		db.connect(); 
		db.close(); 
	} 
}
package com.hspedu.interface_; 
public class InterfacePolyArr { 
	public static void main(String[] args) { 
		//多态数组 -> 接口类型数组 
		Usb[] usbs = new Usb[2]; 
		usbs[0] = new Phone_(); 
		usbs[1] = new Camera_(); 
		/*给 Usb 数组中,存放 Phone 和 相机对象,Phone 类还有一个特有的方法 call(), 
		请遍历 Usb 数组,如果是 Phone 对象,除了调用 Usb 接口定义的方法外, 
		还需要调用 Phone 特有方法 call */ 
		for(int i = 0; i < usbs.length; i++) {
			usbs[i].work();//动态绑定.. 
			//和前面一样,我们仍然需要进行类型的向下转型 
			if(usbs[i] instanceof Phone_) {//判断他的运行类型是 Phone_ 
				((Phone_) usbs[i]).call(); 
			} 
		} 
	} 
}
interface Usb{ 
	void work(); 
}
class Phone_ implements Usb { 
	public void call() { 
		System.out.println("手机可以打电话..."); 
	}
	@Override public void work() { 
		System.out.println("手机工作中..."); 
	} 
}
class Camera_ implements Usb { 
	@Override
	public void work() { 
		System.out.println("相机工作中..."); 
	} 
}

接口的多态特性

1.在前面的usb接口案例中,UsbInterface usb,即可以接收手机对象,又可以接收相机对象 ,体现了类接口的多态

2.多态传递现象:如果ig继承了ih接口,而teacher类实现了ig接口,那么相当于teacher类实现了ih接口,这就是所谓的接口多态传递现象。

3.多态数组问题

例题

package com.hspedu.interface_; 
public class InterfacePolyParameter { 
	public static void main(String[] args) { 
		//接口的多态体现 
		//接口类型的变量 if01 可以指向 实现了 IF 接口类的对象实例 
		IF if01 = new Monster(); 
		if01 = new Car(); 
		//继承体现的多态 
		//父类类型的变量 a 可以指向 继承 AAA 的子类的对象实例 
		AAA a = new BBB(); 
		a = new CCC(); 
	} 
}
interface IF {} 
class Monster implements IF{} 
class Car implements IF{} 
class AAA { }
class BBB extends AAA {} 
class CCC extends AAA {}
package com.hspedu.interface_; 
public class InterfacePolyPass { 
	public static void main(String[] args) { 
		//接口类型的变量可以指向,实现了该接口的类的对象实例 
		IG ig = new Teacher(); 
		//如果 IG 继承了 IH 接口,而 Teacher 类实现了 IG 接口 
		//那么,实际上就相当于 Teacher 类也实现了 IH 接口. 
		//这就是所谓的 接口多态传递现象. 
		IH ih = new Teacher(); 
	} 
}
interface IH { 
	void hi(); 
}
interface IG extends IH{ } 
class Teacher implements IG {
	@Override 
	public void hi() { 
	} 
}
package com.hspedu.interface_; 
public class InterfacePolyArr { 
	public static void main(String[] args) { 
		//多态数组 -> 接口类型数组 
		Usb[] usbs = new Usb[2]; 
		usbs[0] = new Phone_(); 
		usbs[1] = new Camera_(); 
		/*给 Usb 数组中,存放 Phone 和 相机对象,Phone 类还有一个特有的方法 call(), 
		请遍历 Usb 数组,如果是 Phone 对象,除了调用 Usb 接口定义的方法外, 
		还需要调用 Phone 特有方法 call */ 
		for(int i = 0; i < usbs.length; i++) {
			usbs[i].work();//动态绑定.. 
			//和前面一样,我们仍然需要进行类型的向下转型 
			if(usbs[i] instanceof Phone_) {//判断他的运行类型是 Phone_ 
				((Phone_) usbs[i]).call(); 
			} 
		} 
	} 
}
interface Usb{ 
	void work(); 
}
class Phone_ implements Usb { 
	public void call() { 
		System.out.println("手机可以打电话..."); 
	}
	@Override public void work() { 
		System.out.println("手机工作中..."); 
	} 
}
class Camera_ implements Usb { 
	@Override
	public void work() { 
		System.out.println("相机工作中..."); 
	} 
}

内部类

引入原因:

内部类可以直接访问私有属性 ,并且可以体现类与类之间的包含关系

内部类公式

class Outer{// 外部类

         class Inner{//内部类

        }

}

class Other{//外部其他类

 }

内部类的类型

定义在外部类的局部位置上 (比如方法体内)

1)局部内部类(有类名)

2)匿名内部类(没有类名)

定义在外部类的成员位置上

1)成员内部类(不用static修饰)

2)静态内部类(使用static修饰)

内部类使用规范(四大内部类,写了这么久,不看看)

局部内部类和匿名内部类定义在外部类的局部位置,比如方法体中,局部内部有类名,匿名内部类没有    成员内部类 定义在外部类的成员位置,没有static修饰,有static修饰的为静态内部类

1.四个内部类都可以直接访问外部类的所有成员,包括私有的 但是静态内部类只能访问静态    成员 

2.局部内部类和匿名内部类不能添加访问修饰符,因为它们的地位是一个局部变量,但是可    以使用final修饰。成员内部类和静态内部类可以添加修饰符,因为它们的地位就是一个成员

3.作用域:局部内部类和匿名内部类仅仅在定义它的方法或代码块中 

                  成员内部类和静态内部类和外部类其他成员一样,为整个类

4.局部内部类 ==》直接访问==》外部类成员

   匿名内部类 ==》直接访问==》外部类成员

   成员内部类==》直接访问==》外部类成员

   静态内部类 ==》访问==》外部类的静态成员 

5.外部类可以访问局部内部类,成员内部类 和静态内部类 成员  访问方式 :首先创建对象,       再访问。但是外部类不能访问匿名内部类      

6.外部其他类不能访问匿名内部类和局部内部类 ,但是可以访问静态内部类和成员内部类

7.如果外部类和局部内部类,成员内部类,静态内部类或者匿名内部类的成员重名时,默认      遵循就近原则,如果想访问外部类的成员,静态内部类可以使用外部类名.成员。其他内        部类则可以使用外部类名.this.成员去访问 。   

例如:System.out.println("外部类的n2 = "+ 外部类名.this.n2);

8.匿名内部类的语法比较奇特,因为匿名内部类即是一个类的定义,同时它本身也是一个对      象,因此从语法上来看,他既有定义类的特征,也有创建对象的特征,对前面代码分析可      以看出这个特点,因此可以调用匿名内部类方法

内部类例题

 局部内部类例题

(如果第一道题都看不下去 那你别学了)

package Innerclass;
//演示局部内部类的使用
public class LocalInnerClass {
    public static void main(String[] args) {
        Outer02 P1 = new Outer02();
        P1.m1();//创建Outer方法,调用有内部类的方法,
                // 然后再从方法中创建对象,调用内部类中的成员
    }
}
class Outer02{
    private int n1=100;
    public void m1(){
        //局部内部类是定义在外部类的局部位置,通常在方法
        class  Inner02{//(局部内部类本质是一个类)
                       //不能用访问修饰符去修饰,但是可以被final修饰
                       //可以直接访问外部类的所有成员,包含私有的
            private int n1 =500;
            public void f1(){
                System.out.println("n1= "+n1);// n1=500
                //m1();
                //局部内部类与外部类的成员方法名相同
                //利用就近原则访问局部内部类
                //利用外部类名.this.成员方法名的方式访问外部类
                System.out.println(n1);//500
                System.out.println(Outer02.this.n1);//100
            }
        }
        Inner02 inner02 = new Inner02();
        inner02.f1();//创建对象调用方法,可以访问到内部类成员
    }
}
 匿名内部类例题

1.这道题涉及到

匿名内部类的源码 (建议反复观看)

package com.hspedu.innerclass; 
/**
* 演示匿名内部类的使用 
*/ 
public class AnonymousInnerClass { 
	public static void main(String[] args) { 
		Outer04 outer04 = new Outer04(); 
		outer04.method(); 
	} 
}
class Outer04 { //外部类 
	private int n1 = 10;//属性 
	public void method() {//方法 
		//基于接口的匿名内部类 
		//1.需求: 想使用 IA 接口,并创建对象 
		//2.传统方式,是写一个类,实现该接口,并创建对象 
		//3.老韩需求是 Tiger/Dog 类只是使用一次,后面再不使用 
		//4. 可以使用匿名内部类来简化开发 
		//5. tiger 的编译类型 ? IA 
		//6. tiger 的运行类型 ? 就是匿名内部类 Outer04$1 
		/* 
			我们看底层 会分配 类名 Outer04$1
			class Outer04$1 implements IA { 
				@Override 
				public void cry() { 
					System.out.println("老虎叫唤..."); 
				} 
			} 
		*/ 
		//7. jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1 实例,并且把地址 
		// 返回给 tiger 
		//8. 匿名内部类使用一次,就不能再使用

 
		IA tiger = new IA() { 
			@Override 
			public void cry() { 
				System.out.println("老虎叫唤..."); 
			} 
		}; 
		System.out.println("tiger 的运行类型=" + tiger.getClass()); 
		tiger.cry(); 
		tiger.cry(); 
		tiger.cry(); //实例用多少次都行,但匿名内部类只能使用一次
		// IA tiger = new Tiger(); 
		// tiger.cry(); 
		//演示基于类的匿名内部类 
		//分析
		//1. father 编译类型 Father 
		//2. father 运行类型 Outer04$2 
		//3. 底层会创建匿名内部类 
		/* 
			class Outer04$2 extends Father{ 
				@Override 
				public void test() { 
					System.out.println("匿名内部类重写了 test 方法"); 
				}
			}
		*/ 
		//4. 同时也直接返回了 匿名内部类 Outer04$2 的对象 
		//5. 注意("jack") 参数列表会传递给 构造器 
		Father father = new Father("jack"){ 
			@Override 
			public void test() { 
				System.out.println("匿名内部类重写了 test 方法"); 
			} 
		}; //如果把方法体去掉,则运行类型为father
		System.out.println("father 对象的运行类型=" + father.getClass());//Outer04$2 
		father.test(); 
		//基于抽象类的匿名内部类 
		Animal animal = new Animal(){ 
			@Override
			void eat() { 
				System.out.println("小狗吃骨头..."); 
			}
		}; 
		animal.eat();
	}
}
interface IA {//接口
	public void cry();
}
class Father {//类
	public Father(String name) {//构造器 
		System.out.println("接收到 name=" + name);
	}
	public void test() {//方法
	}
}
abstract class Animal { //抽象类
	abstract void eat();
}

 2.匿名内部类的第二道例题

package com.hspedu.innerclass; 
public class InnerClassExercise02 { 
	public static void main(String[] args) {
		CellPhone cellPhone = new CellPhone();
		cellPhone.alarmClock(new Bell() {
			@Override
			public void ring() {
				System.out.println("懒猪起床了");
			}
		});
		cellPhone.alarmClock(new Bell() {
			@Override
			public void ring() {
				System.out.println("小伙伴上课了");
			}
		});
	}
}
interface Bell{ //接口
	void ring();//方法
}
class CellPhone{//类
	public void alarmClock(Bell bell){//形参是 Bell 接口类型
		System.out.println(bell.getClass());
		bell.ring();//动态绑定
	}
}

 成员内部类例题

(或许看到这就感觉到枯燥 乏味,但是只剩下两道例题了,加油)

package com.hspedu.innerclass;
public class MemberInnerClass01 {
	public static void main(String[] args) {
		Outer08 outer08 = new Outer08();
		outer08.t1();
		//外部其他类,使用成员内部类的三种方式
		// 第一种方式
		// outer08.new Inner08(); 相当于把 new Inner08()当做是 outer08 成员
		// 这就是一个语法,不要特别的纠结.
		Outer08.Inner08 inner08 = outer08.new Inner08();
		inner08.say();
		// 第二方式 在外部类中,编写一个方法,可以返回 Inner08 对象
		Outer08.Inner08 inner08Instance = outer08.getInner08Instance();
		inner08Instance.say();
	}
}
class Outer08 { //外部类
	private int n1 = 10;
	public String name = "张三";
	private void hi() {
		System.out.println("hi()方法...");
	}
	//1.注意: 成员内部类,是定义在外部内的成员位置上
	//2.可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
	public class Inner08 {//成员内部类
		private double sal = 99.8;
		private int n1 = 66;
		public void say() {
			//可以直接访问外部类的所有成员,包含私有的
			//如果成员内部类的成员和外部类的成员重名,会遵守就近原则.
			//可以通过 外部类名.this.属性 来访问外部类的成员
			System.out.println("n1 = " + n1 + " name = " + name + " 外部类的 n1=" + Outer08.this.n1);
			hi();
		}
	}
	//第二种方法,返回一个 Inner08 实例
	public Inner08 getInner08Instance(){
		return new Inner08();
	}
	//写方法
	public void t1() {
		//使用成员内部类
		//创建成员内部类的对象,然后使用相关的方法
		Inner08 inner08 = new Inner08();
		inner08.say();
		System.out.println(inner08.sal);
	}
}
 静态内部类例题

(最后一题 ,马上就要成功了)

package Innerclass;

public class StaticInnerClass {
    public static void main(String[] args) {

        Li li = new Li();
        li.setbus();

        //外部其他类访问内部类方法
        //第一种方式,直接创建静态内部类的对象
        Li.bus b1 = new Li.bus();
        b1.r2();
        //第二种方式,调用普通成员方法返回静态内部类
        Li.bus b2 = li.getbus();
        System.out.println(b2.r1);
        //第三种方式,调用静态成员返回静态内部类
        Li.bus b3 = Li.getbus_();
        b3.r2();

    }

}
class Li{
    public static int num =888;
    public int t1 = 99;
    public void hello(){
        System.out.println("你好");
    }
    public static class bus{
        public int r1=55;
        public void r2(){
            System.out.println("num = "+num);
        //    System.out.println("y1= "y1);//不可以访问非静态成员
        }

    }
    public void setbus(){//外部类访问内部类方法
        bus u1 = new bus();
        System.out.println(u1.r1);
        u1.r2();
    }

    public bus getbus(){//其他类访问内部类方法2
        return new  bus();
    }
    public static bus getbus_(){//其他类访问内部类方法3
        return new  bus();
    }
}

类的五大成员:

1)属性 

2)方法

3)构造器 

4)代码块 

 5)内部类

你可能感兴趣的:(jvm,java)