Java复习,Java知识点以及Java面试题(二)

面向对象:封装,继承,多态


类:相关属性和行为的集合。 对象:该类的具体体现 

成员变量和局部变量的区别:

  位置:成员变量在类中方法外;局部变量在方法定义中或者方法声明上。

  内存中的位置:成员变量在堆内存;局部变量在栈内存。

  生命周期:成员变量随着对象的创建而存在,随着对象的消失而消失;局部变量随着方法的调用而存在,随着方法的调用完毕而消失

       初始化值:成员变量有默认初始化值;局部变量没有默认初始化值,必须定义,赋值,然后才能使用。

匿名对象:仅仅只调用一次的时候,匿名对象调用完就是垃圾,可以被GC回收

  用法:匿名对象可以直接调用方法,也可以作为实际参数传递

封装:指隐藏对象的属性和实现细节,仅对外提供公共访问方法。提高代码复用性,提高代码安全性。

  原则:将不需要对外提供的内容隐藏起来。把属性隐藏,提供公共方法对其访问。

  private关键字:被private修饰的成员变量或成员方法只能在本类中访问。

  this关键字:当前类的对象引用 

  构造方法:给对象的数据进行初始化,方法名与类名相同,没有返回值类型,没有返回值。

创建对象做了哪写事情:Student s = new Student();

  把Student.class文件加载到内存

  在栈内存给s变量开辟一个空间

  在堆内存为学生对象申请一个空间

  给成员变量进行默认初始化

  给成员变量进行显示初始化

  通过构造方法给成员变量进行初始化

  数据初始化完毕,把堆内存的地址值赋值给s变量

 static关键字(修饰成员变量,成员方法):针对多个对象有共同的成员变量的时候,Java提供static关键字来修饰

  特点:随着类的加载而加载

     优先于对象存在

     被类的所有对象共享

     可以通过类名来调用,也可以通过对象名调用

      静态修饰的内容:与类相关的,类成员

  注意事项: 

     A. 静态方法中没有this关键字:静态是随着类的加载而加载,this是随着对象的创建而存在。静态比对象先存在

     B. 静态方法只能访问静态的成员变量和静态成员方法。非静态方法可以访问静态或非静态成员变量,也可以访问静态或非静态的成员方法 

      

静态变量和成员变量的区别

  所属:静态变量属于类,所有也称为类变量;成员变量属于对象

  内存中的位置:静态变量存储于方法区的静态区;成员变量存储于堆内存

  内存出现时间不同:静态变量随着类的加载而加载,随着类的消失而消失;成员变量随着对象的创建而存在,随着对象的消失而消失

  调用:静态变量可通过类名调用,也可通过对象调用;成员变量只能通过对象名调用

main方法是静态的,不需要创建对象,通过类名就可以,方便JVM调用

继承:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,多个类无需再定义这些属性和行为,只要继承即可,通过extends关键字实现类与类的继承

  好处:提高代码复用性,提高代码维护性,让类与类产生关系,是多态的前提

  弊端:耦合性增强了,打破了封装性

  特点:Java只支持单继承,不支持多继承,支持多层继承

子类不能继承父类私有方法,只能继承父类所有非私有的成员;子类不能继承父类的构造方法,但是可以通过super关键字去访问父类的构造方法;不要为了部分功能而去继承,当子类需要使用父类的所有方法的时候去使用继承,体现“B is a A”的关系。

继承中成员变量的关系:

  1)子类中的成员变量和父类中的成员变量不一样。

  2)  子类中的成员变量和父类中的成员变量一样。(就近原则)

      在子类方法中访问一个变量的查找顺序:

        子类方法的局部范围找---->子类的成员范围找----->父类的成员范围找

super关键字:代表父类存储空间的标识(可以理解为父类的引用,可以操作父类的成员)

继承中构造方法的关系:

  1)子类中所有的构造方法默认都会访问父类中空参数的构造方法

  2)子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。

子类的每一个构造方法的第一条语句默认都是:super()

使用super关键字可以去调用父类的带参构造方法

一个类的初始化过程:成员变量初始化,默认初始化,显示初始化,构造方法初始化

子父类的初始化(分层初始化):先进行父类初始化,然后进行子类初始化

继承中成员方法的关系:

  通过子类调用方法:先找子类---->再找父类

方法重写:子类中出现了和父类中方法声明一模一样的方法

  注意事项:父类中私有方法不能被重写,因为父类私有方法子类根本就无法继承

       子类重写父类方法时,访问权限不能更低。最好一致

方法重写和方法重载的区别:

  方法重写override:在子类中出现和父类一样的方法声明的现象

  方法重载overload:在同一个类中,出现的方法名相同,参数列表不同的现象

This和super的区别:

  this代表当前类的引用

  super代表父类的储存空间标识(可以理解为父类的引用,通过super访问父类的成员)

final关键字:可以修饰类,方法,变量

  final修饰类,该类不能被继承

  final修饰方法,该方法不能被重写。(覆盖,复写)

  final修饰变量,该方法不能被重新赋值,此时这个变量就是常量

final关键字修饰局部变量:

  final修饰基本类型,值不能变。

  final修饰引用变量,是指地址值不变。

fina修饰变量的初始化时机:

  被final修饰的变量只能赋值一次

  在构造方法完毕前。(非静态的常量)

多态:同一个对象(事物),在不同时刻体现出来的不同状态

  前提:要有继承关系或者接口实现关系,要有方法重写,要有父类或者父接口 引用指向子类对象

多态中的成员访问特点:(父类 f = new 子类(); )

  1)成员变量:编译看左边,运行看左边。

  2)构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化

  3)成员方法:编译看左边,运行看右边

  4)静态方法:编译看左边,运行看左边(静态和类相关,算不上重写,所以访问还是左边的)

好处:提高代码的维护性(继承保证了这个优点)

   提高了代码的扩展性

弊端:不能使用子类的特有功能

对象间转型问题:

  向上转型:父类 f = new 子类();

  向下转型:子类 z = (子类)f;   要求该父对象必须是能够转换为Zi的

  ClassCastException:类型转换异常,可能发生在向下转型中。

  

抽象类

  抽象类的特点:

    抽象类和抽象方法必须用abstract修饰

    抽象类中比一定有抽象方法,但是有抽象方法的类必须定义为抽象类

    抽象类不能实例化

      因为它不是具体的。

      抽象类有构造方法,但是不能实例化 ?构造方法的作用是什么。用于子类访问父类数据的初始化

    抽象类的子类:

      a. 如果不想重写抽象方法,该子类是一个抽象类

      b. 重写所有的抽象方法,这个时候子类是一个具体的类

    抽象方法不能有主体

    抽象类的实例化其实是靠具体的子类实现的,是多态的方法

        Animal a = new Cat();

  抽象类的成员特点:

    成员变量:既可以是变量也可以是常量

    构造方法:有,用于子类访问父类数据的初始化

    成员方法:既可以是抽象的也可以的非抽象的

  抽象类的成员方法特性:

    A:抽象方法,强制要求子类做的事情

    B:非抽象方法,子类继承的事情,提高代码复用性

  面试问题: 一个类如果没有抽象方法,可以不可以定义为抽象类,有什么意义:

          可以,不让创建对象,不能new实例化

       抽象类不能和哪些关键字共存:

          private 冲突(非法的修饰符组合);final 冲突;static 无意义。

接口

  特点:

  接口用关键字Interface表示:interface 接口名{}

  类实现接口用implements表示:class 类名 implements 接口名 {}

  接口不能实例化:按照多态的方式来实例化

  接口的子类:可以是抽象类但是意义不大;可以是具体类,要重写接口中的所有抽象方法。

  由此可见多态的体现: 具体类多态,抽象类多态,接口多态

  成员特点

    成员变量:接口中的变量默认是常量,并且是静态的。默认修饰符:final, static

    构造方法:接口没有构造方法。

    成员方法:接口方法必须是抽象的。默认修饰符:public abstract

  类与类:继承关系,只能单继承,可以多层继承。

  类与接口:实现关系,可以单实现,也是可以多实现。并且还可以在继承一个类的同时实现多个接口

  接口与接口:继承关系,可以单继承,也可以多继承

抽象类和接口的区别:
  成员区别:抽象类:成员变量:可以变量,也可以常量

           构造方法:有

           成员方法:可以抽象,也可以非抽象

       接口:成员变量:只可以常量

          成员方法:只可以抽象 

  关系区别:

    类与类:继承,单继承

    类与接口:实现,单实现,多实现

    接口与接口:继承,单继承 ,多继承

类名作为形式参数:需要该类的对象

抽象类名作为形式参数: 需要该抽象类的子类对象

接口名作为形式参数:需要该接口的实现类对象

类名作为返回值类型:返回该类的对象

抽象类名作为返回值类型:返回该抽象类的子类对象

接口名作为返回值类型:返回该接口的实现类对象

权限修饰符:

      本类中  同一个包下(子类和无关类)不同包下(子类) 不同包下(无关类)

  private:  Y    N            N        N

  defualt   Y    Y            N        N

  protected Y    Y            Y        N

  public    Y    Y            Y        Y

修饰符:

  权限修饰符:private,defualt,protected, public

  状态修饰符:static,final

  抽象修饰符:abstract

类:权限修饰符:defualt, public;状态修饰符:final;抽象修饰符:abstract

成员变量:权限修饰符:private,defualt,protect, public;状态修饰符:final;抽象修饰符:abstract

构造方法:权限修饰符:private,defualt,protected, public

成员方法:权限修饰符:private,defualt,protect, public;状态修饰符:static,final;抽象修饰符:abstract

比较常见的:public static final int X = 10;

      public static void show() {}

      public final void show() {}

      public abstract void show();

内部类:

  定义在其他类中的类。

  特点:直接访问外部的成员,包括私有

     外部类要访问内部类的成员,必须创建对象。

  位置:在成员位置定义的类为成员内部类;直接访问内部类的成员:外部类名.内部类名 对象名 = 外部类对象.内部类对象;成员内部类被static修饰后的访问:外部类名.内部类名 对象名 = new 外部类名.内部类名()

       成员内部类的修饰符:private 为了保证数据的安全性;static 为了方便访问数据 静态内部类访问的外部类数据必 须用静态修饰

     在局部位置定义的 类为局部内部类;可以直接访问外部类的成员;在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能;

  

 1 /*
 2     面试题:
 3         要求请填空分别输出30,20,10。
 4         
 5     注意:
 6         1:内部类和外部类没有继承关系。
 7         2:通过外部类名限定this对象
 8             Outer.this
 9 */
10 class Outer {
11     public int num = 10;
12     class Inner {
13         public int num = 20;
14         public void show() {
15             int num = 30;
16             System.out.println(num);
17             System.out.println(this.num);
18             //System.out.println(new Outer().num);
19             System.out.println(Outer.this.num);
20         }
21     }
22 }
23 class InnerClassTest {
24     public static void main(String[] args) {
25         Outer.Inner oi = new Outer().new Inner();
26         oi.show();
27     }    
28 }

面试题:

  局部内部类访问局部变量的注意事项?

    A:局部内部类访问局部变量必须用final修饰

    B:为什么:局部变量是随着方法的调用而调用,随着调用完毕而消失,而推内存的内容并不会消失。所以,加入final修饰。加入final修饰后,这个变量就成了常量。既然是常量,就消失了。

匿名内部类:

  内部类的简化写法

  前提:存在一个类,抽象类或者是接口

  格式:new 类名抽象类名或者接口名(){重写方法;}

  本质是什么?该类的子类,抽象类的子类,接口的实现类的匿名对象

 1 /*
 2     匿名内部类面试题:
 3         按照要求,补齐代码
 4             interface Inter { void show(); }
 5             class Outer { //补齐代码 }
 6             class OuterDemo {
 7                 public static void main(String[] args) {
 8                       Outer.method().show();
 9                   }
10             }
11             要求在控制台输出”HelloWorld”
12 */
13 interface Inter { 
14     void show(); 
15     //public abstract
16 }
17 
18 class Outer { 
19     //补齐代码
20     public static Inter method() {
21         //子类对象 -- 子类匿名对象
22         return new Inter() {
23             public void show() {
24                 System.out.println("HelloWorld");
25             }
26         };
27     }
28 }
29 
30 class OuterDemo {
31     public static void main(String[] args) {
32         Outer.method().show();
33         /*
34             1:Outer.method()可以看出method()应该是Outer中的一个静态方法。
35             2:Outer.method().show()可以看出method()方法的返回值是一个对象。
36                 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
37         */
38     }
39 }

 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------

代码块:

  局部代码块:局部位置,用于限定变量的生命周期,及尽早释放提高内存利用率

  构造代码块:在类中的方法外出现,把多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行,一般对对象进行初始化

  静态代码块:在类中的方法外出现,用static修饰,一般是对类进行初始化。

静态代码块,构造代码块,构造方法的执行顺序?

  静态代码块--->构造代码块--->构造方法

  且静态代码块只执行一次,构造代码块每次调用构造方法都执行

原文地址:https://www.cnblogs.com/AICROC/p/13021081.html