黑马程序员之————内部类与子类实例化



------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------



----Java之---------子类的实例化过程

 

 



1, 子类实例化的时候会默认访问父类中的空参构造函数。

 

2,在子类的构造函数中第一行有一个默认的隐式语句。super();

 

3,如果父类中没有空参构造函数,那么子类的构造函数必须用 super明确调用的父类的哪个构造函数

 

4,如果子类构造函数使用了this调用本类的构造函数时,那么super就没有了,

 

但必须保证子类其他构造函数访问父类的构造函数。 

 

5 ,如果子类初始化一定要访问父类。父类初始化完成后在子类初始化

 

顺序———————子类的初始化顺序———————

 

先进行类的装载,1,父类的静态成员和静态代码块2,子类的静态成员和静态代码块3, 父类实例成员和实例初始化块 4. 父类构造方法 5. 子类实例成员和实例初始化块 6. 子类构造方法 

 

6, 一个对象实例化过程: 

 

Person p = new Person(); 

 

1,JVM会读取指定的路径下的Person.class文件,并加载进内存, 并会先加载Person的父类(如果有直接的父类). 

 

2,在堆内存中的开辟空间,分配地址。 

 

3,并在对象空间中,对对象中的属性进行默认初始化。 

 

4,调用对应的构造函数进行初始化。 

 

5,在构造函数中,第一行会先到调用父类中构造函数进行初始化。 

 

6,父类初始化完毕后,在对子类的属性进行显示初始化。 

 

7,在进行子类构造函数的特定初始化。 

 

8,初始化完毕后,将地址值赋值给引用变量.

 

[2] final 关键字--------------------------

 

1,final是一个修饰符,可以修饰类,方法,变量。 

 

2,final修饰的类不可以被继承。 

 

3,final修饰的方法不可以被覆盖。 

 

4,final修饰的变量是一个常量,只能赋值一次。

 

5 ,写法规范:常量所有字母都大写,多个单词,中间用_连接。 

 

public static final double MY_PI = 3.14; 

 

[3]-抽象类----abstract--------------- 

 

1,抽象类定义:如果定义的方法没有方法体,其方法的具体实现由子类完成,该方法就称为抽象方法,包含抽象方法的类就是抽象类。都用abstract修饰。

 

2,抽象类不可以被实例化。因为调用抽象方法没意义。 

 

3,抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化 

 

4,抽象类中是否有构造函数? 有,用于给子类对象进行初始化。

 

5,抽象类可以不定义抽象方法吗? 可以的。目的就是不让该类创建对象。

 

6,抽象关键字不可以和那些关键字共存? 

 

private 不行 方法私有后,子类没法继承

 

static 不行 static修饰的变量随着类的加载而初始化。而抽象类不能被实例化。

 

final 不行 修饰以后子类没法继承

 

7,抽象类一定是个父类 ,因为需要子类覆盖其方法后才可以对子类实例化。

 

8,抽象类和一般类的异同点。

 

相同点: 

 

抽象类和一般类都是用来描述事物的,都在内部定了成员。 不同: 

 

1,一般类有足够的信息描述事物。 抽象类描述事物的信息有可能不足。 

 

2,一般类中不能定义抽象方法,只能定非抽象方法。 

 

抽象类中可定义抽象方法,同时也可以定义非抽象方法。 

 

3,一般类可以被实例化。 抽象类不可以被实例化。

 

abstract class Demo { 

 

abstract /*抽象*/ void say(); }

 

[4]-接口--interface------------------

 

1 ,定义:接口是特殊的抽象类。接口中只有抽象方法 

 

2 ,接口的成员都有固定的修饰符。 接口中的成员都是公共的权限.

 

------1,全局常量: public static final 

 

-------2,抽象方法。public abstract 

 

interface Demo {

 

public static final int ADD = 3;

 

public abstract void say1();

 

public abstract void say2();

}

3,接口不可以实例化。 只能由实现了接口的子类,覆盖了接口中所有的抽象方法后,该子类才可以实例化。 

 

4, Java中,一个接口可以继承多个接口,一个类可以实现多个接口,

 

interface A {

 

void show();

 

}

 

interface B {

 

void method();

}

 

interface C extends A, B {// 接口与接口之间是继承关系,而且接口可以多继承。

 

void function();

}

 

class D implements C {

 

// 覆盖3个方法。

 

public void show() {

}

 

public void method() {

}

 

public void function() {

}

 

}

 

public class Y {

 

public static void main(String[] args) {

 

Y t = new Y();

 

t.show();

 

}

 

private void show() {

// TODO Auto-generated method stub

 

}

 

}

5 ,特点---------------

 

----------1,接口是对外暴露的规则

 

----------2,接口是程序功能的扩展

 

----------3,接口降低了耦合性

 

----------4,类与接口是实现关系,并且一个类可以实现多个接口

 

----------5,接口接口是继承关系,并且一个接口可以继承多个接口 

 

[5]----------接口和抽象类异同点

 

相同点: 

 

都是不断向上抽取而来的。 

 

不同点: 

 

1,抽象类需要被继承,而且只能单继承。 接口需要被实现,而且可以多实现。 

 

2,抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽-----象方法。 接口中只能定义抽象方法,必须由子类去实现。 

 

3,抽象类的继承,是is a关系,在定义该体系的基本共性内容。

 

---- 接口的实现是 like a 关系,在定义体系额外功能。

 

[6]------- 多态------

 

1,定义:就是一个对象对应着不同的类型。

 

2,代码中的体现:父类或接口的引用指向子类的实例。

 

3,好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容。

 

4,弊端:前期定义的内容不能使用(调用)后期子类特有的内容。

 

5,前提:1,必须有关系,继承或实现2,要有覆盖。

 

6, 例子:向上转型与向下转型

 

class A {

 

void printA() {

 

System.out.println("hello-------A");

 

}

 

abstract class A1 {

 

public abstract void printA1();

 

}

 

interface B {

 

public void printB();

 

}

 

}

 

class X extends A {

 

void printA() {

 

System.out.println("hello-------A");

 

}

 

class M extends A1 {

 

public void printA1() {

 

System.out.println("hello-------A1");

 

}

 

}

 

class Y implements B {

 

public void printB() {

 

System.out.println("hello-------B");

 

}

 

}

 

}

 

public class Demo2 {

 

public static void main(String[] args) {

 

A a = new X();// 向下转型

 

a.printA();

 

A.B b = new X().new Y();

 

b.printB();

 

A.A1 a1 = new X().new M();

 

a1.printA1();

 

}

 

}

7,多态时成员的变化

 

1,成员变量。 

 

编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。 

 

运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。 

 

简单说:编译和运行都参考等号的左边。

 

class Fu {

 

int num = 3;

 

}

 

class Zi extends Fu {

 

int num = 4;

 

}

 

public class DuoTaiDemo3 {

 

public static void main(String[] args) {

 

Zi z = new Zi();

 

System.out.println(z.num);

 

}

 

}

2,成员函数(非静态)。 

 

编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。 

 

运行时:参考的是对象所属的类中是否有调用的函数。 简单说:编译看左边,运行看右边。 因为成员函数存在覆盖特性。 

 

abstract class A {

 

public abstract void printA();

 

interface B {

 

public void printB();

 

}

 

}

 

class X extends A {

 

public void printA() {

 

System.out.print("hello--------A");

 

}

 

class Y implements B {

 

public void printB() {

 

System.out.print("hello--------B");

 

}

 

}

 

}

 

public class Demo3 {

 

public static void main(String[] args) {

 

A.B b = new X().new Y();

 

b.printB();

 

}

 

}

 

 

 

3,静态函数。 

class X extends A {

 

void printA() {

 

System.out.println("hello-------A");

 

}

 

class M extends A1 {

 

public void printA1() {

 

System.out.println("hello-------A1");

 

}

 

}

 

class Y implements B {

 

public void printB() {

 

System.out.println("hello-------B");

 

}

 

}

 

}

 

public class DuoTaiDemo3 {

 

public static void main(String[] args) {

 

A a = new X();// 向下转型

 

a.printA();

 

A.B b = new X().new Y();

 

b.printB();

 

A.A1 a1 = new X().new M();

 

a1.printA1();

 

}

 

 

 

编译时:参考引用型变量所属的类中的是否有调用的静态方法。 

 

运行时:参考引用型变量所属的类中的是否有调用的静态方法。

 

简单说,编译和运行都看左边。 对于静态方法,直接用类名调用即可。

 

[8]-----------内部类------------

 

 

分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。 这时就是还有的事物定义成内部类来描述。

 

定义 :将一个类的定义放在另一个类中 .

 

内部类访问特点: 

 

1,内部类可以直接访问外部类中的成员。 是因为内部类持有了外部类的引用,即外部类名.this。 

 

2,外部类要访问内部类,必须建立内部类的对象。 

 

3 ,内部类也可以存放在局部位置上,但是内部类在局部位置上只能访问局部中被final修饰的局部变量。

 

4 , 如果内部类中定义了静态成员,该内部类也必须是静态的。相反如果内部类是静态的。其成员也必须是静态的。静态内部类相当于外部类。

 

总结:-----------------------------------------

 

(1)接口中可以存在接口,也可以存在类 ------------------------------------

 

例如:

 

interface Test {

 

class A {

 

void print() {

 

System.out.println("hello--------A");

 

}

 

public int a = 1;

 

}

 

}

 

class B implements Test {

 

void method() {

 

System.out.println(new A().a);

 

}

 

}

 

public class Demo1 {

 

public static void main(String[] args) {

 

Test.A b = new Test.A();

 

// 类中的方法可以不用复写

 

b.print();// 输出hello--------A

 

System.out.println(b.a);// 输出1

 

new B().method();// 输出1

 

}

}

(2)类中可以定义类与接口--------------------------------------------

 

例如:

 

class A {

 

void printA() {

 

System.out.println("hello-------A");

 

}

 

abstract class A1 {

 

public abstract void printA1();

 

}

 

interface B {

 

public void printB();

 

}

 

}

 

class X extends A {

 

void printA() {

 

System.out.println("hello-------A");

 

}

 

class M extends A1 {

 

public void printA1() {

 

System.out.println("hello-------A1");

 

}

 

}

 

class Y implements B {

 

public void printB() {

 

System.out.println("hello-------B");

 

}

 

}

 

}

 

public class Demo2 {

 

public static void main(String[] args) {

 

A a = new X();

 

a.printA();

 

A.B b = new X().new Y();

 

b.printB();

 

A.A1 a1 = new X().new M();

 

a1.printA1();

 

}

 

}

(3)内部类,内部接口中的成员可以定义成为private,protect,它们就相当于外围类的一个成员---------------------------------------------------

 

(4) 内部类的构造函数为private,它还是可以从其外围类中进行实例化

 

public class Fu {

 

int num = 3;

 

private class Inner {

 

private Inner() {

}; // 内部类的构造函数为private,

 

private int m = 4;

 

}

 

public static void main(String[] args) {

 

Inner z = new Fu().new Inner();// 它还是可以从其外围类中进行实例化

 

System.out.println(z.m);

 

}

 

}

(5)private的类通常用于内部使用,更多用于返回一个指向外部接口的向上转型的引用

 

(6)当内部类为public或者是包妨问权限时,可以在外围类之外的其他中实例化它,除此之处,内部类可以继承、覆盖.

 

(7)非嵌套类的内部类进行实例化时,需要一个指向外围类的引用,即先实例化外围类,再实例化内部类。

 

(8)内部类用于实现多继承

 

(9)内部类可以妨问外围类的所有成员(包括private成员)

 

(10)当一个类要实现两个接口,但是,两个接口有部分方法是相同的,这时,可以用一个内部类来实现其中一个接口,当然,这种情况不只是发生在同时实现两个接口的情况。

 

(11)接口的成员必然是public的。

 

interface Test {

 

class A {

 

void print() {

 

System.out.println("hello--------A");

 

}

 

public int a = 1;// 注意----接口的成员必然是public的。

 

}

 

}

 

class B implements Test {

 

void method() {

 

System.out.println(new A().a);

 

}

 

}

 

public class Demo1 {

 

public static void main(String[] args) {

 

Test.A b = new Test.A();

 

// 类中的方法可以不用复写

 

b.print();// 输出hello--------A

 

System.out.println(b.a);// 输出1

 

new B().method();// 输出1

 

}

 

}

 

(12)接口中的成员在被实现时可以将其实现为private或者是其他权限

 

(13)局部内部类的作用域在对应代码块中,不能在其前面加权限修饰符

 

(14)匿名内部类要使用其外围类中的成员变量,这此变量必须是final的。不然将会在编译时抛出错误。

 

(15)可以不实现一个接口的内部接口!

 

[9]嵌套类型的分类-------------------------------------------

 

一,静态嵌套类型

 

1,静态嵌套类。(在接口内部的类总是静态的,在类内部的静态类是顶级内部类,随着外部类的加载而加载)

 

2,静态嵌套接口(接口总是静态的) 

 

二,非静态嵌套类型(即非静态嵌套类)

 

1,非静态嵌套类(也就是内部类)

 

内部类可以直接使用外围类的成员,也可以访问外围类的基类

 

外围类也可以访问内部类的成员(包括私有成员)

 

内部类可以包含内部类和嵌套接口 

 

class Unrelated extends Outer.Inner {

 

Unrelated(Outer ref) { //提供Inner的外围类对象

 

ref.super();

 

}

 

}

 

[10] 内部类的分类------------------------

 

1,成员内部类:相当于类的成员

 

----1.修饰: 有private protected public final abstract等修饰。

 

--------------------但是成员内部类中,不能定义静态static成员

 

----2.访问:(1)内部类调用外部类,访问外部类中与内部类同名的实例变量用-- 外部类名.this.变量名--- 若不同名可以直接访问。

 

------------(2) 从外部类内调用内部类:外部类的非静态方法访问成员内部类

 

与在外部类外部访问成员内部类一样

 

------------(3)在外部类外部访问内部类成员,与外部类的静态方法访问成员内部类一样

 

2 ,静态内部类:相当于类的静态成员:

 

----1.修饰:静态内部类可以用public,protected,private修饰

 

静态内部类中可以定义静态或者非静态的成员

 

-----2.访问:(1)内部类调用外部类,静态内部类只能访问外部类的静态成员,包括静态变量和静态方法

 

--------------(2)外部类访问内部类的静态成员:内部类.静态成员

 

外部类访问内部类的非静态成员:实例化内部类即可

 

--------------(3)在外部类外部方法静态内部类的对象可以直接生成:

 

用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。

 

3 ,局部内部类:相当于类方法内的成员变量

 

-----1.修饰: 没有修饰。在局部类中,不能定义静态static成员。

 

-----2.访问:(1)内部类调用外部类,有同名,外部类名.this.内部类变量名 访问的是外部类变量若没同名的可以直接调用。

 

--------------(2) 从外部类调用内部类: new Inner(k);写在该方法内。

 

--------------(3)不可以在在外部类外直接访问内部类对象,只能调用方法,屏蔽了内部类。

 

4 ,匿名内部类:是一种特殊的局部内部类,它是通过匿名类实现接口。

 

匿名内部类的特点

 

1,一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。

 

2,只是为了获得一个对象实例,不许要知道其实际类型。

 

3,类名没有意义,也就是不需要使用到。

 

---------1.修饰:没有修饰,不能定义静态static成员

 

---------2.访问:(1)内部类调用外部类,有同名,外部类名.this.内部类变量名 访问的是外部类变量若没同名的可以直接调用。

 

-----------------(2) 从外部类调用内部类: new Inner(k);写在该方法内。

 

-----------------(3)不可以在在外部类外直接访问内部类对象,只能调用方法,屏蔽了内部类。


------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值