面向对象-基础篇

打印 上一主题 下一主题

主题 890|帖子 890|积分 2670

前言:


  • 引出类与对象(oop) -- 为什么需要类与对象(oop)
  • 例:我有两只小狗,有姓名,年龄,性别,怎么完成该操作?
  1. //用变量
  2. String DogName = "小白";
  3. int DogAge = 6;
  4. char DogSex= '公'
  5. String DogName = "小新";
  6. int DogAge = 6;
  7. char DogSex= '公'
  8. //用数组
  9. String[] Dog = {"小白","6","公"}; //数字类型不明确
  10. String[] Dog = {"小新","6","公"}; //数字类型不明确
复制代码

  • 上面案例中完成了小狗的属性创建,那么现在我想给小狗添加一个爱好怎么办?是不是特别麻烦,如果是100只小狗呢?
类与对象是什么:


  • 看前言已经知道,用变量和数组创建一个猫是多么的麻烦,增加一个属性就需要重复大量代码
  • 类:如猫类 ->  把所有猫的属性和行为提取到该猫类中形成一个类

    • 猫类:是自定义的数据类型,如int就是java提供的数据类型  

  • 对象:如猫类 ->  提供猫类去创建出来的就是对象,猫对象

快速入门:


  • 看下面代码就可知道和原本的变量和数组好处在哪,属性类型明确,添加属性值方便,开发效率高
  1.     public static void main(String[] args) {
  2.         Cat cat1 = new Cat();//创建第一个猫对象
  3.         cat1.name = "小白";//给属性赋值
  4.         cat1.age = 10;
  5.         System.out.println(cat1.name +" "+ cat1.age);//输出属性值
  6.         Cat cat2 = new Cat();//创建第二个猫对象
  7.         cat2.name = "小新";//给属性赋值
  8.         cat2.age = 20;
  9.         System.out.println(cat2.name +" "+ cat2.age);
  10.     }
  11. }
  12. class Cat{//定义一个猫类
  13.     String name;//属性
  14.     int age;
  15. }
复制代码

  • 类属性的不同叫法和细节:
  1. Class Cat{
  2.   String name; // 可以叫 1.属性 2.成员变量 3.字段   
  3.   int[] age;  // 可以放所有基本数据类型和引用类型
  4.   doeble money;      
  5. }
  6. pring(car.name+" "+car.age...)//直接输出属性,会输出属性默认值
  7. //int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,
  8. //boolean false,String null
复制代码

  • 对象内存布图:

 类和对象的内存分配机制:


  • java内存结构分析:

    • 栈:一般存放基本数据类型(局部变量)
    • 堆:一般存放对象或数组
    • 方法区:一般存放常量池和类加载信息

  • java创建对象流程简单分析: 

    • 创建对象然后在方法区加载类信息 -- (只是加载一次,不会创建一个对象加载一次)
    • 在堆中创建空间,进行默认初始化
    • 把栈地址指向对象
    • 进行初始化如:cat,pag = 10; cat.name = "小白"  


 成员方法:


  • 什么是成员方法?就是在类在写一个方法(方法是基础里的知识),和写一个属性是一样的
  • 为什么需要成员方法?:

    • 循环遍历一个数组 是否需要写代码遍历循环,
    • 在遍历一个数组呢,复制粘贴代码在循环一次?那我要改动遍历代码,所有的复制粘贴代码都要改?
    • 解决问题:所以只需要通过调用成员方法,就可以减少代码的复用 

  • 快速入门:
  1. public static void main(String[] args) {
  2.         Cat cat = new Cat();
  3.         cat.show();//调用方法
  4.     }
  5. }
  6. class Cat{
  7.     String name = "小白";
  8. /*
  9.     public 公共的 -- 作用域(当然还有其它的)
  10.     void -- 表示方法没有返回值
  11.     int -- 表示方法返回值,基本数据类型,引用类型都可以
  12.     return -- 表示把值返回
  13.     show-- 方法名
  14.     () -- 形参列表,表示可以接收形参
  15.     {} -- 方法体     
  16. */
  17. public void show(){
  18.   //方法体
  19.    System.out.println("我叫"+name);
  20.   }
  21. <br>//有参返回
  22. public int show2(int i, int n ){
  23.     return i+n;
  24. }
  25. }
复制代码

  •  方法调用机制:


  • 方法的定义:
  1. 访问修饰符 返回数据类型 方法名(形参列表..) {//方法体
  2.             语句;
  3.             return 返回值; //如果是viod就需要该存在了
复制代码
  1. }
复制代码

  • 成员方法的下细节:

    • 一个方法最多一个返回值(但是可以有多个返回结果,返回数组形式)
    • 可以返回任意类型,基本数据类引用类型(数组,对象)
    • 如果方法是void,不需要写return,或者只写return(不能用返回值)
    • 返回值类型return必须和返回值统一或者兼容,如:需要返回值是double,return可以返回int,反过来就不可以需要数据类型可以转换  
    • 遵循驼峰命名法

  1. class Dog{
  2.   //1.返回多个结果
  3.    public int[] king(){
  4.       int[] sum = new int[3];
  5.       sum[0] = 1;
  6.       sum[1] = 2;
  7.      return sum; //返回多个结果   
  8.    }
  9.   
  10.   //2.void可以写return,但不能有返回值
  11.    public void king2(){
  12.      pring("加油");
  13.      return;
  14.    
  15.    }
  16. //3.可以返回兼容的类型
  17.   public double king3(){
  18.      int  i = 99;
  19.      return i ;
  20.    
  21.    }
  22.       
  23. }
复制代码

  • 成员方法 - 形参列表细节:

    • 一个方法可以有0个参数,也可以有多个参数有逗号隔开
    • 参数类型可以是任意类型,基本数据类型或引用类型
    • 调用参数方法时,传入的参数一定是相同的类型或兼容的类型
    • 方法定义时的参数叫形参(形式参数),调用方法时传入的叫实参,实参和形参必须统一或兼容

  1. //一个方法可以有0个参数,也可以有多个参数有逗号隔开
  2.     public int show(int num1, int num2){
  3.         return num1+num2;
  4.     }
  5.     //参数类型可以是任意类型,基本数据类型或引用类型
  6.     public int[][] show2(int[][] map){
  7.         int[][] nums = new int[11][11];
  8.         return nums;
  9.     }
复制代码

  • 成员方法 - 方法体细节:

    • 方法体中不能嵌套方法  



  • 成员方法 - 方法调用细节:

    • 同类中可以直接调用同类中的其它方法
    • 在方法中可以通过对象调用其它类中的方法 - 这里注意因为跨类调用还需要考虑访问修饰符

  1. class A{
  2.     public void print(){
  3.         System.out.println("我在同类中的其它方法调用了");
  4.     }
  5.     //同类中可以直接调用其它方法
  6.     public void sayOK(){
  7.         print();
  8.         System.out.println("我调用了print()方法");
  9.     }
  10.     //在方法中可以,通过对象调用其它类方法
  11.     public void m1(){
  12.         System.out.println("A的m1被调用");
  13.         new B().hi();
  14.         System.out.println("A的m1现在执行 ");
  15.     }
  16. }
  17. class B{
  18.     public void hi(){
  19.         System.out.println("我是B类的hi()方法");
  20.     }
  21. }
复制代码

  •  成员方法 - 基本数据类型传递机制

    • 基本数据类型传递的是值拷贝,形成不会改变实参 



  •  成员方法 - 引用类型传递机制

    • 引用类型传递的是地址 - 会对引用类型改变
    • 如果在方法中改变了传递过去的地址,改变了地址或指空,那么对引用类型不会进行影响  

 
 方法的重载:


  • 什么是重载?-> 同一个类中,多个方法名称一样的方法存在,但是形成列表不一致
  • 重载的好处 -> 如我的方法是显示加法后的结果,那可以是int加int,doblue加int,那么可以通过同一方法名来实现,只需要传递不同的参数
  1. class AA{
  2.     public void show(int i ,int n){
  3.         System.out.println(i+n);
  4.     }
  5.     public void show(int i ,double n){
  6.         System.out.println(i+n);
  7.     }
  8.     public void show(double i ,double n){
  9.         System.out.println(i+n);
  10.     }
  11.     public void show(double i, int n){
  12.        System.out.println(i+n);
  13.     }
  14.    
  15. }
复制代码

  • 重载细节:

    • 方法名必须相同
    • 形成列表不能一致
    • 可以是任意返回类型(如:可以返回int double void Cat 数组类型 等) 

  1.     //返回形成列表不能一致,返回类型不同也不行
  2.     public void show(double i ,double n){
  3.         System.out.println(i+n);
  4.     }
  5.     public double show(double i ,double n){
  6.         System.out.println(i+n);
  7.     }
复制代码
 可变参数:


  • 什么是可变参数?就是可以传递零个或多个数
  • 使用可变参数,可以当数组使用
  • 语法:int... sum -- 就是int类型的可变参数
  1. public int sum(int... nums){
  2.         int res = 0;
  3.         for (int i = 0; i < nums.length; i++) {
  4.             res += nums[i];
  5.         }
  6.         return res;
  7.     }
复制代码

  • 可变参数 - 细节:

    • 可变参数实参可以是0个或多个
    • 可变参数的实参可以是数组
    • 可变参数本质就是数组
    • 可以参数可以和普通类型参数一起放在形成列表中,可变参数必须放在普通参数后面
    • 一个形成列表,只能出现一个可变参数

  1. public class Test {    public static void main(String[] args) {        AA aa = new AA();        //可变参数的实参可以是数组        int[] num = {1,2,3};        int sum = aa.sum(num);    }}class AA{    public int sum(int... nums){
  2.         int res = 0;
  3.         for (int i = 0; i < nums.length; i++) {
  4.             res += nums[i];
  5.         }
  6.         return res;
  7.     }
  8.     //可以参数可以和普通类型参数一起放在形成列表中,可变参数必须要在普通类型参数后面    public void sum(String name,int... nums){    };
  9.     //一个形成列表只能出现一个可变参数    //public void sum(double... num,int... nums){};//错误}
复制代码
作用域: 


  • 什么是作用域?就是属性在该类中的使用范围
  • 作用域一般访问:全局变量和局部变量
  • 全局变量:在该类中都可以使用
  • 局部变量:只能在自己的一亩三分地使用,在自己的代码块中使用
  1. //快速入门
  2. class AA{
  3.     //该属性在AA类中都可以访问
  4.     String name = "king";  //成员变量/属性/全局变量
  5.     public void show(){ //成员方法
  6.         //该属性只能在show()方法中使用
  7.         char sex = '男'; //局部变量
  8.     }
  9. }
复制代码

  • 作用域细节:

    • 全局变量(属性)有默认值;局部变量没有默认值(定义时必须赋值)
    • 全局变量(属性)和局部变量名字可以重复,访问时就近原则,靠我近访问谁
    • 全局变量(属性)可以使用访问修饰符,局部变量不可以
    • 全局变量(属性)伴随着对象的销毁而销毁,局部变量是代码块的销毁而销毁

      • 通俗易懂版:new一个对象,该对象不销毁全局变量还在,局部变量一般中方法中,如方法结束局部变量就销毁  


  1. class AA{
  2.     //1.属性默认值:String是null
  3.     String name;
  4.     //2.属性和局部变量名字可以一致,就近原则访问
  5.     int age;
  6.     //3.属性可以使用访问修饰符
  7.     public char sex;
  8.     public void show(){
  9.         //1.局部变量:没有默认值,不写就错
  10.         char sex = '男';
  11.         //2.属性和局部变量名字可以一致,就近原则访问
  12.         int age = 18;
  13.     }
  14. }
复制代码
 构造器:


  •  什么是构造器?完成对新对象的初始化

    • 理解:调用构造器时,对象已存在内存中,调用构造器去完成对象属性的的初始化
    • 在理解:等于AA类中有 String name; 我的操作等于 String name = "小白"; 

  • 语法:【修饰符】类名 (形参列表) {代码块}
  1. class AA{
  2.     String name;
  3.     int age;
  4.    public AA(String name,int age){
  5.        System.out.println("name+age");
  6.        name = name;
  7.        age = age;
  8.    }
  9. }
复制代码

  • 构造器 - 细节:

    • 可以构造器的重载
    • 控制器没有返回值
    • 控制器名和类名相同
    • 构造器完成对象的初始化,不是创建对象
    • 类中没有定义构造器,系统默认是给一个默认的无参构造器
    • 定义了自定义的构造器后,默认的构造器就会被覆盖,需要重新定义才能使用  


对象创建的流程+构造器版本:


  • 类加载
  • 在堆在分配空间   ==  空对象
  • 对象初始化 - 属性先赋值(默认值先赋值,在到定义值,在到构造器)
  • 栈中接收堆中地址


 this关键字:


  • 什么是this?我直接调用我自己
  • 为什么要使用this?如:构造器中形参为 name 类属性 name 我要name = name怎么办?是不是太含糊不清,谁是谁的name

    • 案例说明什么是,我直接调用我自己:

  1. public class Test {
  2.     public static void main(String[] args) {
  3.         AA aa = new AA("小白",20);
  4.         //1.调用该方法name = null,age = 0
  5.         aa.show();
  6.     }
  7. }
  8. class AA{
  9.     String name;
  10.     int age;
  11.     public AA(String name, int age) {
  12.         //2.因为:这里把name当成了局部变量
  13.         //自己 给 自己 赋值肯定是错误的
  14.         name = name;
  15.         age = age;
  16.         //3.this.name表示当前对象的name属性
  17.         //当前对象是谁?AA aa = new AA("小白",20);
  18.         //所以说是:我自己调用我自己
  19.         this.name = name;
  20.         this.age = age;
  21.     }
  22.     public void show(){
  23.         System.out.println(name+" "+age);
  24.     }
  25. }
复制代码

  • 深入了解,我自己调用我自己:

    • 每个对象都会有一个hashcode,Java可以通过这个hashcode来识别一个对象 




  • this细节:

    • this关键字可以访问,本类属性,方法,构造器

      • 访问方法语法:this.方法名(参数列表)
      • 访问构造器语法:this(参数列表) - 必须写在构造器中使用,必须在构造器中第一条中,不能递归调用(就是我调用你,你调用我)  

    • this关键字可以区分属性和局部变量
    • this关键字只能在类定义的内部使用,去类外部使用谁知道this是什么

  1. class AA{
  2.     String name;
  3.     int age;
  4.     public AA(String name, int age) {
  5.         //this关键字访问本类构造器
  6.         this("小白");
  7.         //this关键字访问本类属性
  8.         this.name = name;
  9.         this.age = age;
  10.     }
  11.     public AA(String name) {
  12.         String name = "oop";
  13.         //this关键字可以区分属性和局部变量
  14.         this.name = name;
  15.         this.age = age;
  16.     }
  17.    
  18.     public void t1(){
  19.         //this关键字可以访问本类方法
  20.         this.t2();
  21.         System.out.println("我是t1");
  22.     }
  23.     public void t2(){
  24.         System.out.println("我是t2");
  25.     }
  26. }
复制代码
 
    
 
 
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表