你能用几句话解释面向对象?(下)

简介: 一种基于面向过程的新的编程思想,顾名思义该思想是站在对象的角度思考问题,我们把多个功能合理的放到不同对象里,强调的是我该让谁来。面向对象最小的程序单元是类,必须先存在类的定义,再有对象,而具备某种功能的实体,称为对象。

九、关键字(this、super)


9.1、this关键字


this关键字表示当前对象(谁调用this所在的方法,this就是哪一个对象主要)存在于两个位置:


  1. 在构造器中:表示当前创建的对象
  2. 在方法中:哪一个对象调用this所在的方法,此时this就表示哪个对象


什么时候需要使用this关键字


  1. 为了解决局部变量和成员变量之间的二义性,此时必须使用
  2. 同一个类中非static方法之间的互相调用,此时可以省略,但是基本不会省略
  3. 调用本类其他的构造方法


public class Dog {
  private String name;
  private int age;
  public Dog() {
  }
  public Dog(String name) {
    this(name, 0);// 调用两个参数的构造器(构造器之间的重载),必须放在构造器第一行
  }
  public Dog(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public void say() {
    String name = "局部变量";
    System.out.println(name); // 访问局部变量
    System.out.println(this.name);// 访问成员变量
    this.other();// 调用当前类中非static方法
  }
  public void other() {
    System.out.println(this.age);//此时的this是谁
  }
}
复制代码


this内存图


9.JPG


this关键字表示当前对象本身,一般用于类的内部,其内部存在一个地址,指向当前初始化对象本身

当new一个对象的时候,实际上产生了两个引用,一个是供Dog内部调用其他成员变量或者成员方法的this关键字,另一个是供外界程序调用实例成员的dog持有类信息


9.2、super关键字


super表示当前对象的父类对象,在创建子类对象的时候,在子类构造器的第一行会先调用父类的构造器


super虽然表示父类对象,但是他仅仅只是一个关键字,内部并没有地址,所以不能够引用


什么时候使用super


  1. 访问父类中非私有的实例方法,此时必须使用super
  2. 在子类的构造器中,调用父类的构造器,此时必须使用super
  3. 如果想访问父类的非私有成员变量,此时必须使用super


父类:


public class Person {
  private String name;
  private int age;
  public Person() {
  }
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public void doWork() {
    System.out.println("Person...doWork...");
  }
}
复制代码


子类:


public class Student extends Person {
  private String sn;
  public Student(String sn) {
    super();// 隐式调用父类无参数构造器,必须作为构造第一行
    this.sn = sn;
  }
  public Student(String name, int age, String sn) {
    super(name, age);// 显示去调用父类有参数构造器,必须作为构造第一行
    this.sn = sn;
  }
  public void doWork() {
    super.doWork(); //  此时调用父类的doWork()方法
    this.doWork();  //  此时调用自己的doWork()方法
    System.out.println("Student...doWork...");
  }
}
复制代码


总结


  1. super调用构造方法必须写在子类构造方法的第一行
  2. 如果子类构造方法没有显示调用父类构造方法时,那么JVM会默认调用父类的无参构造器


十、修饰符(static、final)


10.1、static修饰符


static修饰的字段和方法都直接属于类,不属于该类的对象(字段和方法属于谁,就让谁来调用)


  • 有static修饰的变量和方法:属于类,直接用类名调用即可,在同一个类中调用可以省略类名不写
  • 没有static修饰的变量和方法:属于对象,必须先创建对象,然后用对象调用


注意:static方法不能使用super和this关键字


因为static是类级别的,super和this是对象级别的,存在类的时候不一定存在对象,也就说使用类名调用static方法时,此时可能是没有对象的。
复制代码


10.1.1、静态方法


static修饰的方法称为静态方法,归类所有,也称为类方法


修饰符 static 返回值类型 方法名(形参列表){
}
复制代码


静态方法有两种访问方式:

  1. 类名.静态方法名()
  2. 对象.静态方法名()Java是不推荐这种访问机制的


静态方法的特性


  1. 静态方法中可以访问静态变量和其他静态方法
  2. 实例方法中可以访问静态成员变量以及静态成员方法


10.1.2、静态变量


在类中,用static关键字修饰的成员变量称为静态变量,归类所有,也称为类变量,类的所有实例对象都可以访问,被类的所有实例或者对象共享


static 数据类型 成员变量
复制代码


静态变量的访问


  1. 类名.静态变量
  2. 类的对象.静态变量(Java不推荐


10.2、final修饰符


final的含义是最终的,不可改变的,可以修饰类、方法、变量,他是来限制某个类不可以有子类,不可以覆盖方法


final修饰的类


表示最终的类,该类不可以再拥有子类


final public class Super {
}
public class Sub  extends Super{  //此行语法报错
}
复制代码


final修饰的方法


最终的方法,该方法不可以被子类覆盖


public class Super {
  final public void doWork() {
  }
}
public class Sub  extends Super{
  public void doWork() {    //此行语法报错
  }
}
复制代码


final修饰的变量


表示常量,该变量只能赋值一次,不可以再重新赋值

  • 基本数据类型:表示的值不能再改变
  • 引用数据类型:所引用的地址不可以再改变


final int age = 17;
age = 100;  //此行语法报错
final Dog d = new Dog();
d.setAge(5);  //d的字段值是可以改变的 
d = new Dog();  //此行语法报错
复制代码


十一、代码块


直接使用{}括起来的一段代码区域,代码块里面的变量属于局部变量,仅在{}内有效

他有三种存在形式:普通代码块、构造代码块、静态代码块


11.1、普通代码块


直接定义在方法内部的代码块,一般的,不会直接使用局部代码块的,结合if、while、for等关键字使用,表示一块代码区域,作用域可以嵌套


public class CodeBlockDemo {
  public static void main(String[] args) {
    System.out.println("begin...");
    {
      //直接使用代码块,一般不用
      int age = 17;
    }
    System.out.println(age);  //此行报错,超出age作用范围,就不能访问到了
    if (100 > 5) {
      System.out.println("100 > 5");
    }
    System.out.println("end...");
  }
}
复制代码


11.2、构造代码块


构造代码块在类的内部,方法的外部,随着一个对象的创建而执行一次,在构造方法前执行


package day09_ObjectAdvanced.Classing.StaticBlock;
/**
 * @author Xiao_Lin
 * @version 1.0
 * @date 2020/12/9 16:29
 */
public class Dog {
  private String name;
  static String age="111";
  {
    System.out.println("我是构造代码块");
  }
  public Dog(){
    System.out.println("我是无参构造方法");
  }
  public Dog(String name){
    System.out.println("我是有参构造方法");
  }
  public void shut(){
    System.out.println("我是叫方法");
  }
}
复制代码


10.JPG


如果需要在构造方法执行前加载一些资源(如读配置文件、XML文件等等),我们可以把构造对象前的一切操作都放在构造代码块中执行


11.3、静态代码块


用static关键字所修饰的代码块称为静态代码块,位于类的内部、方法的外部,且只执行一次,在构造代码块、构造方法前执行


package day09_ObjectAdvanced.Classing.StaticBlock;
/**
 * @author Xiao_Lin
 * @version 1.0
 * @date 2020/12/9 16:29
 */
public class Dog {
  private String name;
  static String age="111";
  static {
    System.out.println("我是静态代码块");
  }
  {
    System.out.println("我是构造代码块");
  }
  public Dog(){
    System.out.println("我是无参构造方法");
  }
  public Dog(String name){
    System.out.println("我是有参构造方法");
  }
  public void shut(){
    System.out.println("我是叫方法");
  }
}
复制代码


11.JPG


十二、内部类


12.1、类的组织方式


12.1.1、类和类的平行关系


一个文件可以定义多个类,但只能存在一个public类,且文件的名字和public类的名字要保持一致


public class Dog{
}
class Cat{
}
复制代码

网络异常,图片无法展示
|


Dog和Cat地位一样,和分开定义两个文件是一模一样的

12.1.2、类和类之间包含关系


public class Outer {
  public class Inner{
 }
}
复制代码


Outer和Inner是包含关系,Outer称为外部类,而Inner称为内部类,内部类Inner作为一个Outer的成员而存在


12.JPG


12.2、内部类的概述


什么是内部类,把一个类定义在另一个类的内部,把里面的类称之为内部类,把外面的类称之为外部类,内部类的分类有:


  1. 成员内部类
  2. 静态内部类
  3. 方法内部类
  4. 匿名内部类


12.3、匿名内部类


当一个类只使用一次,可以声明成匿名内部类

匿名内部类 必须有实现存在,多以实现接口居多


public class Outer {
  public void print(){
/*
class Inner implements AInterface{
@Override
public void showInfo() {
System.out.println("inner.showInfo");
}
}
new Inner().showInfo();
*/
/*
AInterface aInterface = new AInterface(){
@Override
public void showInfo() {
System.out.println("inner.showInfo");
}
};
aInterface.showInfo();
*/
// 通过匿名类创建匿名对象
    new AInterface(){
      @Override
      public void showInfo() {
        System.out.println("inner.showInfo");
      }
    }.showInfo();
  }
}
复制代码


十三、枚举类


枚举是一种特殊的类,固定一个类只能有哪些对象


13.1、枚举类的定义


public enum 枚举类型{
  常量对象A、常量对象B、常量对象C
}
复制代码
publicc enum Story{
    HISTORY、ENGLISH、MATH
}
复制代码


我们自定义的枚举类都是在底层直接继承了 java.lang.Enum 类,枚举中都是全局公共的静态常量,可以直接用枚举类名调用


Stroy story = Story.ENGLISH;
复制代码


因为java.lang.Enum类是所有枚举类的父类,所以所有的枚举对象可以调用Enum类中的方法


String  name = 枚举对象.name();     //  返回枚举对象的常量名称
int ordinal  = 枚举对象.ordinal();  //  返回枚举对象的序号,从0开始
复制代码


注意:枚举类不能使用创建对象



相关文章
|
3月前
|
Java C++ 开发者
"深度剖析!接口VS抽象类、聚合VS组合...这6大OOP谜题,你真的全解开了吗?点击揭秘真相!"
【8月更文挑战第19天】接口与聚合是面向对象编程的关键,对于构建灵活、可扩展的软件系统至关重要。本文澄清六个常见疑惑:接口与抽象类的区别、为何使用接口、聚合与组合的不同、接口的新特性、聚合与继承的关系,以及如何合理选择接口、聚合和继承,助你深刻理解并准确应用这些核心概念。
38 0
|
6月前
|
C#
C#的类和对象的概念学习案例刨析
【5月更文挑战第17天】C#是一种面向对象的语言,以类和对象为核心。类作为对象的模板,定义了属性(如Name, Age)和行为(如Greet)。对象是类的实例,可设置属性值。封装通过访问修饰符隐藏实现细节,如Customer类的私有name字段通过Name属性访问。继承允许新类(如Employee)从现有类(Person)继承并扩展。多态让不同对象(如Circle, Square)共享相同接口(Shape),实现抽象方法Area,提供灵活的代码设计。
67 1
|
6月前
|
人工智能 算法
【算法】深入理解 Prolog:逻辑编程的奇妙世界
【算法】深入理解 Prolog:逻辑编程的奇妙世界
158 0
|
PHP 开发者
|
11月前
|
算法
lingo中的一些概念解释
lingo中的一些概念解释
103 0
|
Java 程序员 C语言
用最通俗易懂的方法解释什么是面向对象
用最通俗易懂的方法解释什么是面向对象
82 0
|
存储 C++
C++ Primer Plus 第十一章答案 使用类
只有聪明人才能看见的摘要~( ̄▽ ̄~)~
67 0
|
编译器 C++
C++ Primer Plus 第十四章答案 C++中的代码重用
只有聪明人才能看见的摘要~( ̄▽ ̄~)~
65 0
|
C++
C++ Primer Plus 第十章答案 对象和类
只有聪明人才能看见的摘要~( ̄▽ ̄~)~
81 0
|
C++
C++ Primer Plus 第十三章答案 类继承
只有聪明人才能看见的摘要~( ̄▽ ̄~)~
71 0
下一篇
无影云桌面