随笔 - 33,  文章 - 0,  评论 - 0,  阅读 - 8276

面向对象

面向过程和面向对象的理解:

用面向过程的方法写出来的程序是一份蛋炒饭,而用面向对象写出来的程序是一份盖浇饭。所谓盖浇饭,北京叫盖饭,东北叫烩饭,广东叫碟头饭,就是在一碗白米饭上面浇上一份盖菜,你喜欢什么菜,你就浇上什么菜。我觉得这个比喻还是比较贴切的。

蛋炒饭制作的细节,我不太清楚,因为我没当过厨师,也不会做饭,但最后的一道工序肯定是把米饭和鸡蛋混在一起炒匀。盖浇饭呢,则是把米饭和盖菜分别做好,你如果要一份红烧肉盖饭呢,就给你浇一份红烧肉;如果要一份青椒土豆盖浇饭,就给浇一份青椒土豆丝。

蛋炒饭的好处就是入味均匀,吃起来香。如果恰巧你不爱吃鸡蛋,只爱吃青菜的话,那么唯一的办法就是全部倒掉,重新做一份青菜炒饭了。盖浇饭就没这么多麻烦,你只需要把上面的盖菜拨掉,更换一份盖菜就可以了。盖浇饭的缺点是入味不均,可能没有蛋炒饭那么香。

到底是蛋炒饭好还是盖浇饭好呢?其实这类问题都很难回答,非要比个上下高低的话,就必须设定一个场景,否则只能说是各有所长。如果大家都不是美食家,没那么多讲究,那么从饭馆角度来讲的话,做盖浇饭显然比蛋炒饭更有优势,他可以组合出来任意多的组合,而且不会浪费。

盖浇饭的好处就是”菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是”可维护性“比较好,”饭” 和”菜”的耦合度比较低。蛋炒饭将”蛋”“饭”搅和在一起,想换”蛋”“饭”中任何一种都很困难,耦合度很高,以至于”可维护性”比较差。软件工程追求的目标之一就是可维护性,可维护性主要表现在3个方面:可理解性、可测试性和可修改性。面向对象的好处之一就是显著的改善了软件系统的可维护性。

面向对象的本质

以类的方式组织代码,以对象的方式组织(封装)数据。

抽象:

把很多同样的东西抽取出来放在一起。

对象 是具体的事物。

类 是抽象的,对对象的抽象。

三大特性

封装 继承 多态

调用方法:

 

    public static void main(String[] args) {
       //调用静态方法
       demo03.asd();
       //调用非静态方法 先实例化这个类
       demo01 demo01 = new demo01();
       demo01.aad();
  }

static 是和类一块加载的,非静态方法是类实例化之后才存在的。

 

构造方法

定义

类中的构造器也称为构造方法,是在进行创建对象的时候必须调用,并且构造器有以下两个特点:

1 必须和类名相同;

2必须没有返回类型,也不能写void;

作用:

1、使用new关键字本质是在调用构造器(通过new去走构造器)

2、初始化值

注意点

定义了有参构造,如果想使用无参构造,必须显示的定义无参构造

public class Dog {
   String name;
   int age;

   public static void play(){
       System.out.println("玩耍");
  }
//无参构造器
   public Dog() {
  }
//有参构造器
   public Dog(String name, int age) {
       this.name = name;
       this.age = age;
  }
}

封装

高内聚,低耦合

高内聚 就是类的11内部数据操作细节自己完成,不允许外部干涉

低耦合 仅暴露少量的方法给外部使用

属性私有,get/set


public class Dog01 {
   //属性私有
   private String name;
   private int age;
   //get、set
   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public int getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }
}
 public static void main(String[] args) {
       Dog01 dog01 = new Dog01();
       dog01.setName("多多");
       dog01.setAge(1);
       System.out.println(dog01.getName());
       System.out.println(dog01.getAge)
  }

继承

继承就是扩展,子类对父类的扩展。

super this注意点
  1. super调用父类的构造方法,必须在构造方法的第一个

  2. super 必须只能出现在子类的方法或者构造方法中

  3. super和this不能同时调用构造方法

     

    VS this

    代表的对象不同

    this:本身调用者这个对象

    super 代表父类对象的应用

    前提:

    this没有继承也可以使用

    super只有在继承条件下使用

    构造方法

    this() 调用本类的构造

    super()调用父类的构造

     

方法重写

静态方法(不能被重写)

classA

public class A extends  B{
   public static void test(){
       System.out.println("A=>test");
  }
}

classB

public class B {
   public static void test(){
       System.out.println("B=>test");
  }
}

C

public class demo01 {
   public static void main(String[] args) {
       A a = new A();
       a.test();
       //父类的引用指向子类
       B b = new A() ;
       b.test();
  }
}

输出结果是:

A=>test
B=>test

 

非静态方法

classA

public class A extends  B{
   @Override
   public void test() {
       System.out.println("A=>test");
  }
}

classB

public class B {
   public static void test(){
       System.out.println("B=>test");
  }
}

C

public class demo01 {
   public static void main(String[] args) {
       A a = new A();
       a.test();
       //父类的引用指向子类
       B b = new A() ;
       b.test();
  }
}

输出结果是:

A=>test
A=>test

 

总结:

即b是A new出来的对象,因此调用了A的方法,因为静态方法是类的方法,而非静态方法是对象的方法,有static时,b调用了B类的方法,因为b是用b类定义的。没有static是,b调用的是对象的方法,而b是用A类new的。

重写:(发生在父子类)

1.方法名必须相同

2 参数列表必须相同

3修饰符 子类的大于等于父类的 public>protected>default>private

4 抛出的异常范围得比父类的小

子类的方法和父类的方法必须一致,方法体不同

为什么需要重写?

父类的功能,子类不一定需要,或者不一定满足

多态

即同一方法可以根据发送对象的不同而采用不同的行为方式

package com.polymorphism;

public class Person {
   public void run(){
       System.out.println("run");
  }


}
package com.polymorphism;

public class Student extends Person {
   @Override
   public void run() {
       System.out.println("Student run");
  }

   public void eat(){
       System.out.println("studnet eat");
  }
}
import com.polymorphism.Person;
import com.polymorphism.Student;

public class Application {
   public static void main(String[] args) {
       //一个对象的实际类型是确定的 比如new Person() new Student()
       //可以指向的引用类型就不确定了:父类的引用指向子类
       Person p1 = new Person();
       //Student是子类,能调用的方法是自己的或是父类的
       Student s1 = new Student();
       //Person是父类,可以指向子类,但不能调用其方法
       Person s2 = new Student();

       //对象能执行那些方法主要看等号左边的引用类型 和右边关系不大
       p1.run();
       s1.run();//子类若是没有重写父类方法,则调用父类的;重写后调用子类的。
       s2.eat();// 报错 Person中没有eat方法
  }
}
注意事项:

多态是方法的多态,属性没有多态

父类和子类,有联系,类型转换异常:ClassCastException!

多态存在条件:有继承关系,方法需要重写

什么方法不能重写?

static 属于类,不属于实例

final 常量

private 私有的

Instanceof

判断两个类是否存在父子关系

        Object object = new Student(); //object指向的对象是student类型的
       System.out.println(object instanceof Object);//true
       System.out.println(object instanceof Person);//true
       System.out.println(object instanceof Student);//true
       System.out.println(object instanceof Teacher);//false
       System.out.println(object instanceof String);//false

       System.out.println("===================");

       Person person = new Student();//person指向的对象是Student类型的
       System.out.println(person instanceof Person);//true
       System.out.println(person instanceof Student);//true
       System.out.println(person instanceof Teacher);//false
       System.out.println(person instanceof Object);//true

       System.out.println("================");

       Student student= new Student();//person指向的对象是Student类型的
       System.out.println(student instanceof Person);//true
       System.out.println(student instanceof Student);//true
      /* System.out.println(student instanceof Teacher);*///编译不通过,爆红。原因是 student类和 teacher无关系
       System.out.println(student instanceof Object);//true
 System.out.println(x instanceof y);

1 能否编译通过看类,x和y的类 若存在父子关系 则能编译通过

2 编译通过后 true或false看引用指向的对象 x只想的对象如果是后面y的子类 及时true

Person person = new Student();

System.out.println(person instanceof Person);

比如 person 的类是Person

引用指向的对象是Student

类型转换

父类转子类 向下转型 强制转换 可能会丢失一些方法

    //高转底
      Person person = new Student();
       Student aa = (Student)person;
       Person person1 = new Person();
       Student aasd = (Student)person1;

 

子类转父类 向上转型

   Student student = new Student();
       Person person = student;

Static

public class StaticTest {
   //属性
   private int a;
   private static double b;
   //方法
   private void run(){
       System.out.println("run");
  }
   private static void go(){
       System.out.println("go");
  }
   public static void main(String[] args) {
       //调用
       //非静态属性 通过类对象调用
       StaticTest staticTest = new StaticTest();
       System.out.println(staticTest.a);
       //静态属性 通过类名直接调用
       System.out.println(StaticTest.b);
       //非静态方法调用
       staticTest.run();
       //静态方法
       StaticTest.go();
  }
}

 

执行顺序

注意:static只执行一次

public class CodeArea {
  {
       System.out.println("匿名代码块");
       //一般附一些初始值
  }
   static {
       System.out.println("静态代码块");
  }
   //构造方法

   public CodeArea() {
       System.out.println("构造方法");
  }

   public static void main(String[] args) {
       CodeArea codeArea = new CodeArea();
  }
}

//结果
静态代码块
匿名代码块
构造方法

抽象类

1.不能new抽象类 只能靠子类趋实现 约束。子类继承抽象类就得必须实现他的所有方法。

2 抽象类中可以写普通方法

3抽象方法必须写在抽象类中。

接口

 

接口实现类命名 ***Impl

侧面实现多继承,接口只有方法的定义。

一个类可以实现多个接口,但只能继承一个类。

接口作用:

1 约束

2 定义一些方法 让不同人去实现

3 接口方法默认是public abstract

属性默认是常量 public static final

4 接口不能被实例化 接口没有构造方法

内部类

内部类 就是一个类的内部定义一个类,比如A类中定义一个B类,n那么B类相对A类来说就是内部类,A相对于B类来说就是外部类

1 成员内部类
public class outer {
   private int id = 10;
   public void out(){
       System.out.println("外部类");
  }
   public class inner {
       public void in(){
           System.out.println("成员内部类");
      }
       public void getId(){
           //可以获得外部类的私有属性 或调用私有方法
           System.out.println(id);
      }

  }
}
public class application {
   public static void main(String[] args) {
       outer outer = new outer();
       outer.out();
       //通过外部类实例化内部类
       com.innerclass.outer.inner inner = outer.new inner();
       inner.getId();
  }
}

 

2 静态内部类
public class outer {
   private int id = 10;
   public void out(){
       System.out.println("外部类");
  }
   public static class inner {
       public void in(){
           System.out.println("静态内部类");
      }
     //静态内部类不能访问外部类的属性

  }
}

 

3 局部内部类
public class MemberClass {
   //局部内部类 写在方法中的
   public void method(){
       class MemberInner{
           public void aa(){
               System.out.println();
          }
      }

  }
}

 

4 匿名内部类
public class Test {
   public static void main(String[] args) {
       //没有名字初始化类 不用将实例保存在变量中
       new Apple().eat();
       //一般是先实例化
       /*Apple apple = new Apple();
       apple.eat();*/
       //接口也可以
       new UserService(){
           @Override
           public void run() {
               
          }
      };

  }
}
   class Apple{
   public  void eat(){
       System.out.println("eat");
  }
  }
   interface UserService{
       void run();
  }
 
posted on   可惜君已逝i  阅读(280)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示