2、java容易忘记的面向对象基础知识

本文深入讲解Java中的关键概念,包括类变量与局部变量的区别、构造方法的作用、静态变量与静态方法的特点、封装与继承的运用、多态的概念及其实现方式、内部类的使用场景以及final关键字的多重含义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 类中变量
   成员变量在类中定义说明对象将要有什么java会给成员变量一个初始值
   局部变量在类的方法中定义在方法中临时保存的数据java不会给局部变量一个初始值

2 构造方法
   有参构造方法给类中属性赋值
   无参构造方法默认实例化调用
   有参构造方法与无参构造方法是可以共存的但是不会同时触发根据创建对象时候的传的参数取决于调用哪个
   
3 静态变量static修饰的变量为静态变量或类属性所有对象共享此变量如果该类有多个对象其中一个对象将其改变那么其它对象读此值也是改变后的值
   class HelloWorld{
        static String name = "张三";
        public static void main(String[] args){
            System.out.print(HelloWorld.name); //张三
            HelloWorld h1 = new HelloWorld();
            HelloWorld h2 = new HelloWorld();
            System.out.println(h1.name);  //张三
            System.out.println(h2.name);  //张三
            h1.name = "隔壁老王";
            System.out.println(HelloWorld.name); //隔壁老王
            System.out.println(h1.name);  //隔壁老王
            System.out.println(h2.name);   //隔壁老王
        }
   }  
   
4 静态方法static修饰的方法为静态方法或类方法
   4.1  静态方法中可以直接调用同类中的静态成员但不能直接调用非静态成员
   4.2  静态方法中不能直接调用非静态方法需要通过对象来访问非静态方法   
   4.3  在普通成员方法中则可以直接访问同类的非静态变量和静态变量
   

5 普通初始化块静态初始化块
   5.1 普通初始化块在类中被"{}"包含的变量块为普通初始化块无法定义方法
   5.1 静态初始化块在类中被"static{}"包含的变量块为普通初始化块无法定义方法只在类加载时执行且只会执行一次同时静态初始化块只能给静态变量赋值
   不能初始化普通的成员变量
   5.2 程序运行时静态初始化块最先被执行然后执行普通初始化块最后才执行构造方法
   public class HelloWorld {
        int num1;
        int num2;
        static int num3;
        public HelloWorld(){
            num1 = 91;
            System.out.println("通过构造方法给变量num1赋值");
        }
      {
            int num2 = 74;
         System.out.println("通过构造方法给变量num2赋值");
      }
      static{
            int num3 = 83;
         System.out.println("通过构造方法给变量num3赋值");
      }
      
      public static void main(String[] args){
            HelloWorld h1 = new HelloWorld();
         System.out.println("num1:"+h1.num1);
         System.out.println("num1:"+h1.num2);
         System.out.println("num1:"+num3);
      }
   }
   
   #通过构造方法给变量num3赋值
   #通过构造方法给变量num2赋值
   #通过构造方法给变量num1赋值
   #num1:91
   #num1:0
   #num1:0


6 封装在类外部不允许直接操作类内部属性

7 继承子类继承父类只能单继承
   7.1 重写覆盖):子类重写父类方法方法名称返回值参数位置参数类型参数个数都要一样
   7.2 创建对象时候父类属性初始化->父类构造方法->子类属性初始化->子类构造方法
   7.3 Object:所有类的祖宗,Object2个重要的属性
         7.3.1  toString :java中直接输出对象会输出对象在内存的地址如果想在输出对象的时候显示自己想要看到的就要在该对象的类中实例化toString方法
         public class HelloWorld {
                private int cc = 99;
                
                @Override
                public String toString() {
                  return "HelloWorld [cc=" + cc + "]";
                }

            public static void main(String[] args){
                    HelloWorld in  = new HelloWorld();
               System.out.println(in);
            }
         }
         7.3.2 equals():判断两个对象内存地址是否相同但是现实中经常比较两个对象属性是否相等并不是比较对象内存地址这样一来它满足不了我们就要重写它
         默认比较给出答案是"不同1""不同2" #【注】 ==在比较基本数据类型时候是比较值是否相等,但是在比较引用数据类型的时候实际比较的也是内存地址
            public class HelloWorld {
                    private int cc = 99;
                    
                    public static void main(String[] args){
                        HelloWorld hw1  = new HelloWorld();
                        HelloWorld hw2  = new HelloWorld();
                        if(hw1.equals(hw2)){
                        System.out.print("相同1");
                        }else{
                         System.out.print("不同1");
                        }
                                
                        if(hw1== hw2){  #【注】 ==在比较基本数据类型时候是比较值是否相等,但是在比较引用数据类型的时候实际比较的也是内存地址
                            System.out.print("相同2");
                        }else{
                            System.out.print("不同2");
                        }
                    }
            }
         
         重写equals也是有快捷键的与hashcode一起生成用不到hashcode删除就好了):
         给出答案是"相同1""不同2"
            public class HelloWorld {
                    private int cc = 99;
                        public static void main(String[] args){
                        HelloWorld hw1  = new HelloWorld();
                        HelloWorld hw2  = new HelloWorld();
                        if(hw1.equals(hw2)){
                        System.out.print("相同1");
                        }else{
                            System.out.print("不同1");
                  }
                  
                  if(hw1.equals(hw2)){
                            System.out.print("相同2");
                  }else{
                            System.out.print("不同2");
                  }
               }

               @Override
               public boolean equals(Object obj) {
                        if (this == obj) //两个引用的值是否相同(即两个引用的内存地址是否相同)
                             return true;
                        if (obj == null)  //判断传入对象是否是空值 
                            return false;
                        if (getClass() != obj.getClass()) //getClass获取类对象中的属性,判断两个对象类型是否相同;  Xx a = new Xx() 生成的是"类的属性",指的是属性的值
                            return false;
                        HelloWorld other = (HelloWorld) obj; //判断比较的对象是否是当前类的对象
                  if (cc != other.cc) //判断属性值是否相同
                            return false;
                  return true;
               }
            }

         
8 多态对象的多种多态
   8.1 引用多态
      父类的引用可以指向本类的对象
      父类的引用可以执行子类的对象
   8.2 方法多态
      创建本类对象时调用的方法为本类的方法
      创建子类对象时调用的方法为子类重写的方法或者父类的方法当子类没有重写父类的方法就是调用的父类方法否则就调用子类中的方法
      】:如果子类独有的方法父类通过实例化子类实现多态后是不允许调用子类自己的方法的
            Dog是子类Animal是父类,DogwatchDoor方法与run方法Animal中有run方法
            Animal a = new Dog()
            a.run() //方法重载,可以
            a.watchDoor() //不允许的
   8.3 引用类型转换
      8.3.1 向上类型转换(隐式/自动类型转换)小类型大类型无风险 
      8.3.1 向下类型转换(强制类型转换)大类型小类型有风险),装不下益处使用instanceif运算符来解决引用对象的类型避免类型转换的安全性问题
         Dog dog = new Dog()
         Animal animal = dog;//向上转换
         Dog dog2 = (Dog)animal //向下类型抓奴还
         Cat cat = (Cat)animal //【注】编译不报错,运行报错;  编译时认为animalCat,当运行时候发现,真正开辟的空间是Dog,没办法将dog转换为cat,所以用instanceof就会解决这个问题
         //instanceof
         if(animal instanceof Cat){
                Cat cat = (Cat)animal
         }else{
                System.out.println("无法转换");
            }
         】:所以一般在类型转换时候尽量都用instanceof判断
         
   8.4 抽象类
      8.4.1 abstract定义抽象类
      8.4.2 abstract定义抽象方法,只有声明不需要实现
      8.4.3 包含抽象方法的类是抽象类
      8.4.4 抽象类中也可以有普通的方法也可以没有抽象方法
      8.4.5 抽象类不能直接创建可以定义引用变量
          】:抽象类不能被直接实例化
      //子类继承之后必须要实现抽象方法
      public abstract class Test {
            public abstract void test();
            public abstract void test1();
        }
   8.5 接口特殊的类是一种规范interface定义接口是用来被实现的修饰符一般建议用public
      8.5.1 接口都是抽象的interface前如果未定义abstract如果不写系统不会报错运行时候系统会自动给加上一般不写),一般声明那个接口的名字前面都要加I代表接口
      8.5.2 :接口中只能定义常量(public static final修饰)与抽象方法如果写普通方法系统不会报错程序运行时候会自动加上一般不写
      8.5.3 可以实现多个接口实现接口可以用implements),类只能单继承先继承后实现
      8.5.4 实现接口要实现接口中所有方法
      】:不能使用privateprotected接口不能直接实例化
      IPlayGame是游戏接口PSPSmartPhone都实现了它他们都有了玩游戏功能SmartPhone同时又继承了phonePSP不属于phone就不需要继承所以接口使用起来很方便
      IPlayGame  playgame = new Psp()
      IPlayGame  playgame1 = new SmartPhone()
   
   8.6 匿名内部类方式使用接口
      //IPlayGame是一个接口,其中有俩个方法testtest1,匿名内部类方式直接实现
      public static void main(String[] args){
             IPlayGame tt = new IPlayGame(){
                 @Override
                 public void test() {
                     System.out.println('6666')
                 }
                 @Override
                 public void test1() {
                // TODO Auto-generated method stub
                 }
          };
         tt.test() //6666
      }
      
            

9 内部类 内部类 Inner Class 就是定义在另外一个类里面的类与之对应包含内部类的类被称为外部类 
   9.1 内部类提供了更好的封装可以把内部类隐藏在外部类之内不允许同一个包中的其他类访问该类
   9.2 内部类的方法可以直接访问外部类的所有数据包括私有的数据
   9.3 内部类所实现的功能使用外部类同样可以实现只是有时使用内部类更方便
   9.4 内部类种类
         成员内部类
         静态内部类
         方法内部类
         匿名内部类

   //外部类HelloWorld
   public class HelloWorld {
        // 内部类Inner,类Inner在类HelloWorld的内部
        public class Inner {
             // 内部类的方法
            public void show() {
                 System.out.println("welcome to imooc!");
            }
      }
   
      public static void main(String[] args) {
            // 创建外部类对象
            HelloWorld hello = new HelloWorld();
         // 创建内部类对象
         Inner i = hello.new Inner();
         // 调用内部类对象的方法
         i.show();
      }
   }

10 静态内部类 静态内部类是 static 修饰的内部类,不允许同一个包中的其他类访问该类
   10.1: 静态内部类不能直接访问外部类的非静态成员但可以通过 new 外部类().成员 的方式访问 
   10.2: 如果外部类的静态成员与内部类的成员名称相同可通过类名.静态成员访问外部类的静态成员如果外部类的静态成员与内部类的成员名称不相同
   则可通过成员名直接调用外部类的静态成员
   10.3: 创建静态内部类的对象时不需要外部类的对象可以直接创建 内部类 对象名= new 内部类();
   public class HelloWorld {
        private int a = 99;
        public static class Inner{
            public void show(){
                HelloWorld hw = new HelloWorld();
                int b = 6;
                System.out.println("a:" + hw.a);
                System.out.println("b:" + b);
            }
      }

      public static void main(String[] args){
            Inner in  = new Inner();
         in.show();
      }
   }


11 方法内部类 方法内部类就是内部类定义在外部类的方法中方法内部类只在该方法的内部可见即只在该方法内可以使用
         注意】:由于方法内部类不能在外部类的方法以外的地方使用因此方法内部类不能使用访问控制符和 static 修饰符

   public class HelloWorld {
        private int cc = 99;
        public void show(){
            final int A = 25;//常量
            int b = 1; //方法内部类无法访问方法中的变量
            
            class Inner{
                int c = 2;
                public void print(){
                    System.out.print("访问方法内部的常量A"+A); //25
                    System.out.print("访问inner类中的属性c"+c); //2
                    System.out.print("访问HelloWorld类中的属性cc"+cc); //99
                }
            }
            Inner in = new Inner();
            in.print();
      }
      
      public static void main(String[] args){
            HelloWorld in  = new HelloWorld();
         in.show();
      }
   }


12 final 
   修饰类不允许被继承(最终的方法)
   修饰方法不允许被重写(覆盖)
   修饰属性该类的属性不会进行隐式初始化(类的初始化属性必须有值或者在构造中赋值只能选择其一)
         final public int a;
   修饰变量修饰变量则该变量只能被赋一次值即变为常量
         final int a;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值