Java面向对象程序设计

 一. 封装

当我们谈论封装(Encapsulation)时,我们实际上是在讨论面向对象编程(OOP)中的一个重要原则。封装的目标是将数据和操作数据的方法绑定在一起,形成一个单一的单元。这样的单元可以被其他部分轻松地使用,而无需了解其内部实现细节。以下是封装的一些关键小节:

 1. 定义封装:

   - 概念: 封装是将对象的内部状态和行为包装在一个类中,然后通过类的接口来访问和操作它们。

   - 作用: 提高代码的模块化、降低耦合度,同时隐藏实现细节。

 2. 封装的实现:

   - 成员变量私有化: 将类的字段声明为私有,限制直接访问,通过公共方法提供对它们的访问。

   - 方法封装: 控制方法的访问级别,只暴露必要的接口,将内部实现细节隐藏。

 3. 使用访问修饰符:

   - private关键字: 用于限制变量和方法的访问范围,只允许同一类中的其他方法进行访问。

   - public关键字: 用于标识公共方法,可以被其他类调用。

 4. Getter和Setter方法:

   - Getter方法: 提供对私有字段的读取访问,用于获取对象的状态。

   - Setter方法: 提供对私有字段的写入访问,用于修改对象的状态。

 5. 信息隐藏:

   - 隐藏内部实现: 封装通过隐藏对象的内部实现细节,使得对象的使用者只需要关注对象的功能,而不需要了解其具体实现。

   - 减少耦合: 通过封装,对象与外部的耦合度降低,提高了代码的可维护性和灵活性。

 6. 封装与继承、多态的关系:

   - 封装与继承: 封装和继承是面向对象编程的两个核心概念,它们可以相互配合。封装提供了数据的隐藏,而继承提供了代码的复用。

   - 封装与多态: 封装与多态一同支持代码的抽象性。封装通过隐藏实现细节,多态通过允许一个接口表示多个实现来提高代码的灵活性。

 7. 适当的封装级别:

   - 平衡性: 适当的封装级别是一个平衡的问题。过度封装可能导致冗余,不足的封装可能破坏了模块化和隔离性。

 8. 实例化对象的封装:

   - 构造方法: 通过构造方法初始化对象的状态,确保对象在创建时处于一个有效的状态。

   - 初始化块: 使用初始化块进行额外的初始化操作,确保对象的完整性。

封装是面向对象编程的基石之一,它通过将数据和操作数据的方法捆绑在一起,提供了更加安全和可维护的代码。在Java中,正确使用封装有助于构建清晰、可扩展和可重用的代码。 

 二.this相关

在Java中,`this` 是一个关键字,用于表示当前对象的引用。它可以用在实例方法中,指代当前对象的引用,即调用这个方法的对象。

 主要用途:

1. 区分实例变量和参数:

   - 当实例变量与方法的参数名称相同时,使用 `this` 关键字可以明确指出是实例变量还是方法的参数。

       

 public class MyClass {

        private int value;



        public void setValue(int value) {

            this.value = value; // 使用this明确表示实例变量

        }

    }

    

2. 在构造方法中调用其他构造方法:

   - 在一个类的构造方法中,可以使用 `this` 来调用同一类中的其他构造方法,以避免代码重复。

   

    public class MyClass {

        private int value;



        public MyClass() {

            this(0); // 调用另一个构造方法

        }



        public MyClass(int value) {

            this.value = value;

        }

    }

    

3. 返回当前对象:

   - 在方法中返回当前对象的引用,以支持方法链式调用。


    

    public class MyClass {

        private int value;



        public MyClass setValue(int value) {

            this.value = value;

            return this; // 返回当前对象引用,支持链式调用

        }

    }

4. 在匿名类中使用:

   - 在匿名类中,`this` 表示的是当前匿名类的实例。

    

    Runnable myRunnable = new Runnable() {

        @Override

        public void run() {

            // 在匿名类中,this表示当前匿名类的实例

            System.out.println("This is a runnable.");

        }

    };

  

总体来说,`this` 关键字在Java中用于引用当前对象,它提供了一种方式来处理对象内部的成员与方法参数之间的命名冲突,并支持构造方法的调用、链式调用等场景。

三. 继承

继承是面向对象编程中的一个重要概念,它允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法。在Java中,继承通过关键字 `extends` 来实现。

 基本概念:

1. 父类和子类:

   - 父类(基类/超类): 包含通用属性和方法的类。

   - 子类(派生类): 从父类继承属性和方法,并可能添加新的属性和方法的类。

// 父类

    class Animal {

        void eat() {

            System.out.println("Animal is eating.");

        }

    }



    // 子类

    class Dog extends Animal {

        void bark() {

            System.out.println("Dog is barking.");

        }

    }

2. 关键字 `extends`:

   - 使用 `extends` 关键字指定一个类继承自另一个类。

class SubClass extends SuperClass {

        // 子类的成员和方法

    }

 继承的主要特性:

1. 代码重用:

   - 子类可以继承父类的成员变量和方法,从而避免了重复编写相似的代码。

2. 派生类的特化:

   - 子类可以在继承基础上进行扩展,添加新的属性和方法,实现特化。

    class Cat extends Animal {

        void meow() {

            System.out.println("Cat is meowing.");

        }

    }

    

3. 方法覆写:

   - 子类可以提供对父类方法的新实现,称为方法覆写。

class Dog extends Animal {

        @Override

        void eat() {

            System.out.println("Dog is eating bones.");

        }

    }

4. 多态性:

   - 通过继承和方法覆写,可以实现多态性,即一个对象可以以多种形式存在。

    Animal myDog = new Dog(); // 多态性

    myDog.eat(); // 调用的是Dog类的eat方法

    

 注意事项:

1. Java是单继承的:

   - 一个类只能直接继承一个父类,但可以通过接口实现多继承的效果。

2. 构造方法的调用:

   - 子类的构造方法会隐式调用父类的无参构造方法,如果父类没有无参构造方法,需要在子类构造方法中显式调用父类的构造方法。

    class Cat extends Animal {

        void meow() {

            System.out.println("Cat is meowing.");

        }

    }

3. 访问修饰符:

   - 子类不能访问父类中被声明为私有的成员,但可以通过父类的公共方法进行访问。

继承是面向对象编程中一种强大的机制,它提供了代码重用、层次化的组织结构,以及多态性等特性,使得代码更加灵活和易于维护。但在使用继承时,需要注意设计的合理性,避免过度使用和继承链过深等问题。

四.常用关键字

以下是一些常用的Java关键字以及它们的实际应用方法:

1. `public`:

   - 实际应用: 用于声明类、方法或变量是公共的,可以被其他类访问。

public class MyClass {

         public void myMethod() {

             // 公共方法的实现

         }

     }

     

2. `private`:

   - 实际应用: 用于声明类的成员是私有的,只能在类内部访问。

public class MyClass {

         private int myVariable;



         private void myMethod() {

             // 私有方法的实现

         }

     }     

3. `static`:

   - 实际应用: 用于声明静态成员,可以通过类名直接访问。

 public class MathUtils {

         public static int add(int a, int b) {

             return a + b;

         }

   }

  // 调用静态方法

     int result = MathUtils.add(3, 4);

     

4. `final`:

   - 实际应用: 用于声明常量、防止类被继承、防止方法被覆写。  

public final class Constants {

         public static final int MAX_VALUE = 100;

     }



     // 不可继承的类

     public final class MyFinalClass {

         // 类的实现

     }



     // 不可覆写的方法

     public class MyClass {

         public final void myMethod() {

             // 方法的实现

         }

     }

     

5. `abstract`:

   - 实际应用: 用于声明抽象类或抽象方法,需要在子类中实现。

  public abstract class Shape {

         abstract void draw();

     }



     public class Circle extends Shape {

         void draw() {

             // 圆形的绘制

         }

     }

     

6. `interface`:

   - 实际应用: 用于声明接口,一个类可以实现多个接口。

 public interface Drawable {

         void draw();

     }



     public class Circle implements Drawable {

         public void draw() {

             // 圆形的绘制

         }

     }

     

7. `extends`:

   - 实际应用: 用于类之间的继承关系。

 public class Animal {

         // 父类的实现

     }



     public class Dog extends Animal {

         // 子类的实现

     }

8. `this`:

    - 实际应用: 用于引用当前对象,区分实例变量和方法参数,调用其他构造方法。

           

 public class MyClass {

          private int myVariable;



          public void setMyVariable(int myVariable) {

              this.myVariable = myVariable; // 区分实例变量和方法参数

          }



          public MyClass() {

              this(0); // 调用其他构造方法

          }



          public MyClass(int myVariable) {

              this.myVariable = myVariable;

          }

      }

这些关键字在实际应用中帮助构建清晰、灵活且易于维护的Java代码。

五.重载与重写

重载和重写是Java中两个常用的概念,它们分别用于描述在类中定义多个方法时的两种不同情况。

 1. 重载:

- 定义: 在同一个类中,可以定义多个方法,它们具有相同的名字但参数列表不同的特性,这被称为方法的重载。

- 条件: 方法名相同,但参数类型、参数个数或参数顺序不同。

- 示例:

    

public class MathUtils {

      public int add(int a, int b) {

          return a + b;

      }



      public double add(double a, double b) {

          return a + b;

      }

  }

  

  在上面的例子中,`add` 方法被重载,一个接受两个整数,另一个接受两个浮点数。

 2. 重写:

- 定义: 在子类中可以重新定义父类中的方法,这被称为方法的重写。

- 条件: 子类的方法名、返回类型和参数列表必须与父类中的方法一致。子类方法不能比父类方法限制访问权限,但可以比父类方法具有更宽松的访问权限。

- 示例:

   

 class Animal {

      void makeSound() {

          System.out.println("Animal makes a sound");

      }

  }



  class Dog extends Animal {

      @Override

      void makeSound() {

          System.out.println("Dog barks");

      }

  }

  

  在上面的例子中,`Dog` 类重写了 `Animal` 类中的 `makeSound` 方法。

 区别:

1. 参数:

   - 重载: 方法的参数列表不同。

   - 重写: 方法的参数列表必须相同。

2. 返回类型:

   - 重载: 返回类型可以相同也可以不同。

   - 重写: 返回类型必须相同,或是其子类。

3. 方法体:

   - 重载: 只关注方法的签名(方法名和参数列表),不关心方法的实现。

   - 重写: 不仅关注方法的签名,还要求方法的实现发生改变。

4. 关系:

   - 重载: 在同一个类中进行。

   - 重写: 发生在子类与父类之间。

 示例代码:

class Animal {

    void makeSound() {

        System.out.println("Animal makes a sound");

    }

}



class Dog extends Animal {

    @Override

    void makeSound() {

        System.out.println("Dog barks");

    }



    // 重载

    void makeSound(int loudness) {

        System.out.println("Dog barks loudly");

    }

}



public class Main {

    public static void main(String[] args) {

        Dog myDog = new Dog();

        myDog.makeSound();          // 调用重写的方法

        myDog.makeSound(10);        // 调用重载的方法

    }

}

在上面的示例中,`Dog` 类重写了 `makeSound` 方法,并在同一类中进行了重载。在 `main` 方法中演示了如何调用这两个方法。

六.内部类

在Java中,内部类是定义在另一个类内部的类。内部类的存在使得一些设计和编程任务变得更加灵活。内部类有四种主要类型:成员内部类、局部内部类、匿名内部类和静态嵌套类。

 1. 成员内部类:

- 定义: 定义在类的内部,作为类的成员。

- 特点: 可以访问外部类的成员,包括私有成员。

- 示例:

   

 public class OuterClass {

      private int outerVar;



      public class InnerClass {

          public void display() {

              System.out.println("OuterVar from OuterClass: " + outerVar);

          }

      }

  }

  

  在上面的例子中,`InnerClass` 是 `OuterClass` 的成员内部类。

 2. 局部内部类:

- 定义: 定义在方法或作用域块内部。

- 特点: 仅在定义它的块中有效,无法被外部访问。

- 示例:

   

 public class OuterClass {

      public void display() {

          int localVar = 10;



          class LocalInnerClass {

              void printLocalVar() {

                  System.out.println("LocalVar from display method: " + localVar);

              }

          }



          LocalInnerClass localInner = new LocalInnerClass();

          localInner.printLocalVar();

      }

  }

  

  在上面的例子中,`LocalInnerClass` 是 `display` 方法中的局部内部类。

 3. 匿名内部类:

- 定义: 没有显式地命名的类。

- 特点: 通常用于创建一个只需使用一次的类的实例。

- 示例:

    

interface Greeting {

      void greet();

  }



  public class OuterClass {

      public void displayGreeting() {

          Greeting greeting = new Greeting() {

              @Override

              public void greet() {

                  System.out.println("Hello, world!");

              }

          };

          greeting.greet();

      }

  }

  

  在上面的例子中,`Greeting` 接口的实例是一个匿名内部类的对象。

 4. 静态嵌套类:

- 定义: 定义在另一个类的内部,使用 `static` 修饰。

- 特点: 可以直接通过外部类的名字和点操作符来访问,与静态成员类似。

- 示例:

public class OuterClass {

      static class StaticNestedClass {

          void display() {

              System.out.println("Inside StaticNestedClass");

          }

      }

  }

  

  在上面的例子中,`StaticNestedClass` 是 `OuterClass` 的静态嵌套类。

 注意事项:

- 内部类可以访问外部类的私有成员,而外部类不能直接访问内部类的成员。

- 内部类拥有对外部类对象的引用,可以使用 `OuterClass.this` 来访问外部类的对象。

内部类的使用使得 Java 的类设计更加灵活,可以更方便地组织和封装相关的代码。选择使用哪种类型的内部类取决于具体的需求,例如是否需要访问外部类的成员、是否需要在一个方法内部创建类的实例等。

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值