2017 - 10 -15 面向对象

1 静态调用
   静态方法中只能调用静态方法,不能调用非静态。
   可以通过创建对象调用非静态方法
class ArrayDemo{ 
    public  static void  main(String arg[]){
           ...........
     //静态方法
     //printArray(arr);
     //非静态方法
     ArrayDemo ad =new ArrayDemo();
     ad.printArray(arr);
      .......
             }
    //public static void printArray(int[] arr){
                   .....
       }
    public  void printArray(int[] arr){
                   .....
      }
}

   在同一个文件夹下,类定义在两个文件中和定义在一个文件中,其实是一样的。
   虚拟机自动编译其余类文件。。。

   **把构造方法私有,外界就不能在创建对象了。。。所以只能通过静态访问。

2  说明书

  /**
  * 这是针对数组进行操作的工具类
  * @author XXX
  * @version V.1
  */

  /**
  * 这是遍历数组的方法,遍历后的格式是:{元素1,元素2,元素3}
  * @param  arr 这是要被遍历的数组
  */
  /**
  * 这是获取数组中最大值的方法
  * @param   arr 这是要获取最大值得数组的数组
  * @return  返回数组中的最大值
  */
   javadoc -d 目录 -author -version ArrayTool.java

3  jdk文档
(1)  java.lang 包下的类不需要导入,其他的全部需要导入
   要导入:
   java.util.Scanner
(2) 记住看类的版本
(3)  类的结构
   成员变量   字段摘要
   构造方法   构造方法摘要
   成员方法   方法摘要
(4) 学习构造方法
    A:有构造方法   就创建对象
    B:没有构造方法  成员可能都是静态的
(5) 看成员方法
   A:左边 
       是否静态,如果静态,可以通过类名调用
       返回值类型:人家返回什么,就用什么接收
   B:右边
       看方法名:方法名称不要写错
       参数列表:需要什么,给什么,需要几个,给几个

4  代码块
   代码块:在java中,使用{}括起来的代码被称为代码块
   根据位置和声明的不同,可以分为
   局部代码块:局部位置,用于限定变量的生命周期
   构造代码块: 在类中的成员位置,用{}括起来的代码,每次调用构造方法执行前,都会执行构造代码块。
          作用:可以把多个构造方法中的共同代码放到一起。
   静态代码块:在类中的成员位置,用{}括起来的代码,只不过使用static修饰了,在有main方法的类中,优先于main执行。
          作用:一般是对类进行初始化

***面试题?

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

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

    静态代码块:只执行一次。

    构造代码块:每次调用都执行。


class Code{
   //静态代码块
   static{
     int a = 1000;
     System.out.println(a);
}
   //构造代码块
    {
     int x = 10;
     System.out.println(x);
}
   //构造方法
   public Code(){
      System.out.println("code");
}
   //构造方法
   public Code(int a){
      System.out.println("code");
}
}

class CodeDemo{ 
    public  static void  main(String arg[]){
        //局部代码块
        {
           int x = 10;
           System.out.println(x);
    }
        //找不到符号
         System.out.println(x);
}

***5 看程序写结果
class Student{
    static{
      System.out.println("Student 静态代码块");
          }
    {
      System.out.println("Student 构造代码块");
}
     public Student(){
      System.out.println("Student 构造方法");
}
}
class StudentDemo{
    static{
      System.out.println("StudentDemo 静态代码块");
   }
    public static void main(String[] args){
     System.out.println("main方法");
     Student s1 = new Student();
     Student s2 = new Student();
}
}
执行结果:
  StudentDemo 静态代码块
  main方法
  Student 静态代码块
  Student 构造代码块
  Student 构造方法
  Student 构造代码块
  Student 构造方法

6 java中继承
(1)java继承特点
  A:java只支持单继承,不支持多继承
  B:java支持多层继承
(2)java继承注意事项
  A:子类只能继承父类所有非私有的成员(成员方法和成员变量)
   **(其实这也体现了继承的另一个弊端:打破了封装性)
  B:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类的构造方法。
  C:不要为了部分功能而去继承
(3)java继承中成员变量的关系
  A:子类中的成员变量和父类中的成员变量名称不一样时。
  B:子类中的成员变量和父类中的成员变量名称一样时,就近原则。
(4)java继承中构造方法的关系
  A:子类中所有构造方法默认都会访问父类中空参数的构造方法
  B:为什么?
    因为子类会继承父类中的数据,可能还会使用父类的数据。
    所以,子类初始化之前,一定要先完成父类数据的初始化。
    **注意:子类每一个构造方法的第一条语句默认都是:super();
(5)java继承中构造方法的注意事项
    如果父类没有无参数的构造方法,那么子类的构造方法会出现什么现象呢?
    报错!
    如何解决?
    A:在父类中加一个无参数的构造方法。
    B: 通过使用super关键字去显示的调用父类的带参构造方法
    C:子类通过this去调用本类的其他构造方法
         子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
    **注意事项:super()或者this()必须出现在第一条语句上
                否则,就会有父类数据的多次初始化
(6)java继承中成员方法的关系:
    A:子类中的方法和父类中的方法声明不一样时。
    B:子类中的方法和父类中的方法声明一样时。
         通过子类调用方法:
            a:先找子类中,有没有这个方法,有就使用。
            b:再看父类中,有没有这个方法,有就使用。
            c:如果都没有就报错。


***7 继承中的面试题
    A:成员变量的问题
      int x = 10;                //成员变量是基本类型
      Student s = new Student(); //成员变量是引用类型
    B:一个类的初始化过程
          成员变量的初始化
          默认初始化
          显示初始化
          构造方法初始化
    C:子父类的初始化(分层初始化)
       先进行父类初始化,然后进行子类初始化
 
  class X{
         Y b = new Y();
         X(){
           System.out.print("X");
     }
}
  class Y{
       Y(){
         System.out.print("Y");
     }
}
  public class Z extends X{
        Y y = new Y();
        Z(){
            //super();
            System.out.print("Z");
 }
         public static void main(String[] args){
          new Z();
    }
}
    输出结果: YXYZ
    有super出现问题:
       虽然子类中构造方法默认有一个super();
       初始化的时候,不是按照那个顺序进行的。
       而是按照分层初始化进行的。
       它仅仅表示要先初始化父类数据,再初始化子类数据

8 重写

(1)方法重写
   子类中出现了和父类中方法声明一模一样的方法。
   方法重载
   本类中出现的方法名一样,参数列表不同的方法,与返回值无关。

(2)方法重写的注意事项
    A:父类中私有方法不能被重写
           因为父类私有方法子类根本就无法继承
 ***B:子类重写父类方法时,访问权限不能更低
           最好就一致
    C:父类静态方法,子类也必须通过静态方法进行重写
           其实这个算不上重写,但现象确实如此,多态中会介绍。

   java中静态变量和静态方法可以被继承,但是没有被重写而是被隐藏。

   通过子类调用父类的同名的静态成员变量或方法,依然访问的是父类的变量和方法。

   而且,静态不能使用this和super关键字。


***9两个面试题
(1)方法重写(Override)和方法重载(Overload)的区别?方法重载能改变返回值类型吗?
      方法重写:在子类中,出现和父类中一模一样的方法声明的现象。
      方法重载:同一个类中,出现的方法名相同,参数列表不同的现象。
      方法重载能改变返回值类型,因为它和返回值类型无关。
(2)this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。
   this:代表当前类的对象引用
   super:代表父类存储空间的标识(可以理解为父类的引用,通过这个东西可以访问父类的成员)
   场景:
     成员变量:
         this.成员变量
         super.成员变量
     构造方法:
         this(...)
         super(...)
     成员方法:
         this.成员方法
         super.成员方法
    
10  final
 (1)由于继承中方法有一个现象:方法重写
    所以,父类的功能,就会被子类给覆盖掉。
    有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用
    这个时候,针对这种情况,java就提供了一个关键字final
    
 (2)  final 可以修饰类,方法,变量
    特点:
      final可以修饰类,该类不能被继承
      final可以修饰方法,该方法不能被重写
      final可以修饰变量,该变量不能被重新赋值,因为这个变量其实是常量。

 (3)   常量
       A:字面值常量
         " hello" ,10,true
       B:自定义常量
          final int x = 10

***11  final面试题

  (1) final修饰局部变量的问题

       基本类型:基本类型的值不能发生改变

       引用类型:引用类型的地址值不能发生改变,但是该对象的堆内存的值可以发生改变

    class Student{
          int age =10;
 }
    class FianlTest{
      public static void main(String[] args){
           //局部变量是基本数据类型
           final int y = 10;
           //无法为最终变量y分配值
           //y = 100;
           //局部变量是引用类型
           Studnet s = new Student();
           System.out.println(s.age);
           s.age = 100;
           System.out.println(s.age);
           //输出 10 100
           
           final Student ss =new Student();
           System.out.println(ss.age);
           ss.age = 100;
           System.out.println(ss.age);
           //输出 10 100
          
           //重新分配内存空间
           //报错,无法为最终变量ss分配值

           ss = new Student();


    (2)final 修饰变量的初始化时机
           A:被final修饰的变量只能赋值一次
           B:在构造方法完毕前。(非静态的常量)
A:
  class Demo{
        int num = 10;
        final int num2 = 20;
        public Demo(){
            num = 100;
         }
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
}
}
       输出结果为:100 (先初始化成员变量,再初始化构造方法)
  
B:
  class Demo{
        int num = 10;
        final int num2 = 20;
        
        public Demo(){
            num = 100;
            //无法为最终变量num2分配值 会报错
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
       输出结果:报错

C:
  class Demo{
        //int num = 10;
        //final int num2 = 20;
        int num;
        final int num2 ;
        public Demo(){
            num = 100;
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
         输出结果:100 200


D:
  class Demo{
        int num;
        final int num2 ;
    {
        num2= 10;     
}
        public Demo(){
            num = 100;
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
     输出结果:报错 (代码块中已经赋值了)
发布了31 篇原创文章 · 获赞 2 · 访问量 9207
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章