7.Java基础知识:面向对象03

1、代码块

1.1 概念:就是使用大括号括起来的一段代码;

1.2 格式

{
	代码
}

1.3 分类(代码块的按照书写位置):

  • 局部代码块

书写在一个类的局部位置(函数里面的)的代码块就是局部代码块;

局部代码块,因为定义在函数里面,所以不能直接使用,而是通过调用它所在的函数来执行;

局部代码块,可以用来限定变量的使用范围;

  • 成员代码块(根据是否使用static关键字修饰再分类)

静态代码块:静态代码块直接写在类里面,使用static关键字修饰。

构造代码块:也是直接写在类中,但是不需要static关键字修饰。

1.4 类加载顺序 类加载顺序

1.5 对象创建过程 对象创建过程

2、单例设计

2.1 概念

单例设计模式:解决的就是在程序运行过程中,一个类最多只能创建一个对象的问题;

2.2 步骤

1.私有化构造函数;

2.在本类中创建唯一实例对象,使用一个私有静态的成员变量保存

3.对外提供一个公开的静态的函数获供别人获取这个唯一实例对象

2.3 代码实现

  • 饿汉式
class Single{
  //1.私有化构造函数
  private Single(){}
  //2.在本类中创建唯一实例对象,使用一个静态私有成员变量保存
  private static Single single = new Single();
  //3.对外提供一个公开的静态函数
  public static Single getInstance(){
    return single;
  }
}
  • 懒汉式
class Single{
  //1.私有化构造函数
  private Single(){}
  //2.在本类中创建唯一实例对象,使用一个静态私有成员变量保存
  private static Single single = null;
  //3.对外提供一个公开的静态函数
  public static Single getInstance(){
    if(single == null){
      single = new Single();
    }
    return single;
  }
}

3、继承

3.1 概念

java中的继承指的是使用extends关键字在两个类之间建立的一种关系;其中,继承其他类的类,叫做子类(派生类),被其他类继承的类叫做父类(超类、基类);

3.2 格式

class  Fu{}//表示被继承的类,是父类

class  Zi  extends  Fu{}//是继承其他类的类,是子类

3.3 作用:继承,可以使子类直接使用父类的成员

子类继承父类,不能直接使用父类的构造函数和私有成员;

3.4 特点

  • 单一继承:一个类只能直接继承一个父类
  • 多重继承:一个类的父类还可以拥有父类(不能出现交叉继承)
继承

3.5 成员变量特点

  • 子类可以直接使用父类非私有成员变量
  • 子类中写了和父类中同名的成员变量,优先使用子类的

3.6 一般函数特点

  • 子类可以直接使用父类非私有的一般函数
  • 子类中写了和父类中一样格式的一般函数,优先使用子类的

3.7 函数重写override

  • 概念

如果在子类中书写了和父类中一样格式的一般函数,直接使用用的是子类中的函数,这种情况叫做子类重写父类函数;一般开发中,如果直接使用父类函数不能满足子类需求,子类就要重写父类函数;

  • 应用
//需求:描述手机这类事物。原始的手机和现代的手机
class OldPhone{ //表示老式手机
   //打电话
   public void call(String num){
     System.out.println("给"+num+"打电话……");
   }
   //发短信
   public void sendMsg(String num,String msg){
     System.out.println("给"+num+"发信息,内容是:"+msg);
   }
}

class NewPhone extends OldPhone{
   //打电话
   public void call(String num){
     System.out.println("显示来电显示");
     System.out.println("给"+num+"视频通话……");
     System.out.println("显示通话时长");
   }
   //发短信
   public void sendMsg(String num,String msg){
     System.out.println("发送自拍照");
     System.out.println("给"+num+"发语音信息,内容是:"+msg);
     System.out.println("显示对方是否接收,是否查看");
   }
   //玩游戏的功能
   public void playGame(String name){
     System.out.println("再玩"+name);
   }
}

class Test{
   public static void main(String[] args) 
   {
     //创建手机对象
     OldPhone op = new OldPhone();
     String num = "18688888888";
     //打电话
     op.call(num);
     //发短信
     op.sendMsg(num,"约吗?");
   
     //创建新式手机
     NewPhone np = new NewPhone();
     //打电话
     np.call("18888888888");
     //发短信
     np.sendMsg(num,"不约,叔叔我们不约!");
     //玩游戏
     np.playGame("王者荣耀");
   }
}
  • 函数重写格式

1、函数名相同;

2、参数列表相同;

3、函数返回值类型相同;

4、是否是静态的相同;

5、子类重写父类函数,访问权限不能比父类低;

  • 构造方法的使用
class F{
   int a = 10;
   public void show(){
     System.out.println("a = " + a);
   }
   public F(){
     System.out.println("父类构造函数");
     show();
   }
}
class Z extends F{
   int b = 20;
   public void show(){
     System.out.println("a = " + a + " ; b = " + b);
   }
   public Z(){
     System.out.println("子类构造函数");
     show();
   }
}

class Test{
   public static void main(String[] args) {
     new Z();
   }
}
  • 输出结果
父类构造函数
a = 10 ; b = 0
子类构造函数
a = 10 ; b = 20
  • 结论

1、子类实例化,只会创建一个对象;

2、子类实例化,会在子类的对象空间中为父类的非静态成员也分配空间;

3、子类构造函数执行时,会通过隐藏步先调用父类构造函数执行;

4、构造函数执行时,哪个类的构造函数,负责为那个类的非静态成员变量显示赋值;

  • 子类构造函数的部分问题

1、为什么任何一个类(不包含Object)的构造函数中都需要一个super() 语句?

因为除了Object类,每个类都有一个父类;

父类中的非静态成员变量的赋值操作,只能由父类的构造函数去完成;

所以子类的构造函数中,必须先调用父类构造函数,给父类的非静态成员变量显示赋值;

2、子类构造函数中,this() 和 super() 能否同时存在?

不能;

this()和super()都必须放在子类构造函数的第一行;

子类创建对象时,super()只需要执行一遍;

3、如果父类中没有无参构造函数,子类如何实例化?

两种办法:

1、再父类中添加一个无参构造函数;

2、再子类中手动调用父类有参构造函数

4、如果一个类的构造函数全部私有了,还可以有子类吗?

不可以!

私有的成员,只能再本类中使用;

构造函数全部私有了,子类就没法使用了;

而子类构造函数中必须要调用父类构造函数,现在父类中没有构造函数可调用,所以就不行;

4、final关键字

final:最终的,最后的;可以修饰类、变量和函数;

4.1 修饰类

  • 格式:直接写在class关键字前面
  • 作用:表示这个类不能被继承

4.2 修饰函数

  • 格式:直接写在函数的返回值类型前面
  • 作用:表示被修饰的函数不能被重写

4.3 修饰变量

  • 格式:直接写在变量的数据类型前面
  • 作用:表示被修饰的变量中直接保存的数据不能改变

注意:如果修饰的是引用类型的变量,则变量中保存的引用不可改变,但是引用指向的堆内存中的数据可以改变;