12.面向对象

面向对象

面向对象与面向过程

  1. 两者都是一种看待问题、解决问题的思维方式、思想(不是一门语言)
  2. 两者的区别
    • 面向过程:强调的是功能行为
    • 面向对象:强调的是完成功能的对象
  3. 面向对象是基于面向过程的

类与对象

对象

具有特定的功能,能够解决待定问题的实体,就是一个对象

由若干个具有相同的特征和行为的对象的组成的集合,就是一个

  • 注:类是对象的集合,对象时类的个体

识别类的小技巧:一般名词都是类(名词提炼法

类与对象的描述

类的设计

由若干个具有相同的特征和行为的对象的组成的集合,就是一个类,其中,特征用属性表示,行为用方法表示,所谓的属性也就是定义在类中的一个全局变量,在定义类时,使用关键字class

[访问权限修饰符] class 类名 {
	//类体
	//属性:描述所有对象的共有特征
	//方法:描述所有对象共有的方法
}

//例子
public class Person{
    String name;//姓名
    int age;//年龄
    
    public void eat() {}//吃
    public void sleep() {}//睡
}

注意事项

  • 类名:是一个标识符,遵循大驼峰命名法
  • 一个java文件中可以写多个类,但只有一个与文件名相同的类,可以使用public
  • 每一个类在编译后都会生成一个.class字节码文件,以类的名字命名
对象的实例化

实例化对象,其实就是从类中找到一个实体,使用关键字new来进行实例化

//实体类
class Person{
    String name;//姓名
    int age;//年龄
    
    public void eat() {}//吃
    public void sleep() {}//睡
}

//测试类
public class Test1{
   
    public static void main(String[] args) {
        Person person = new Person();
    }
    
}

:使用new实例化对象,是在堆上开辟空间。

匿名对象

  1. 定义:

    匿名对象也就是没有名字的对象。

    因为没有名字,所以当我们想使用匿名对象实现功能时,只能在创建对象的这个时刻使用一次.一旦使用完毕,这个对象我们就再也无法调用,变成了垃圾.系统会通过垃圾回收机制在某个时刻进行内存回收。

  2. 作用:

    内存很宝贵,使用匿名对象可以更好的使用内存(随用随建,用完更快回收),节省内存。

  3. 使用的场景:

    1. 用匿名对象直接作为方法的参数;
    2. 用作匿名内部类。
    //测试类
    public class Test2{
        public static void main(String[] args) {
            Person person = new Person();
            person.age = 50;
            
            new Person();//无名字的对象---匿名对象
            new Person().age = 10;
            
            //作为方法参数
            chat(new Person);
        }
        
        public static void chat(Person person) {
            //一些功能
        }
    }
    
    //实体类
    class Person{
        String name;//姓名
        int age;//年龄
        
        public void eat() {}//吃
        public void sleep() {}//睡
    }
    
  4. 多引用指向一个对象

    //测试类
    public class Test3{
        public static void main(String[] args) {
            
            Person person = new Person();
            Person person1 = person;
            //这里person和person1都指向堆中person那个对象,同一块地址
    
        }
        
    }
    
    //实体类
    class Person{
        String name;//姓名
        int age;//年龄
        
        public void eat() {}//吃
        public void sleep() {}//睡
    }
    

类中的成员访问

成员分类
  • 使用关键字static修饰的属性、方法, 被称为静态属性、静态方法;
  • 没有使用关键字static修饰的属性、方法, 被称为非静态属性、非静态方法, 又被称为实例属性、实例方法。
static关键字
  • 被static修饰的成员就变成了静态的.具有保值功能。
  • 作用:
    • 用于保值
    • 用于工具类的创建
空间分配
  • 静态的成员是属于类的,在类第一次被加载到内存中的时候,就已经分配空间了;(也就是方法区
  • 非静态的成员是属于对象的,在实例化对象的时候分配空间。(也就是堆区
访问规则
  • 静态成员需要使用类访问,非静态成员需要使用对象访问;
  • 静态方法中可以直接访问本类中的静态成员,不能直接访问本类中的非静态成员;
  • 非静态方法中可以直接访问本类中的静态成员,也可以直接访问本类中的非静态成员。
//测试类
public class Test4{
    public static void main(String[] args) {
        
        Person person = new Person();
        
        //实例属性和方法访问依赖对象
        person.name = "kaka";
        person.age = 18;
        person.eat();
        person.sleep();
        
        //静态属性和方法依赖类,但对象也能够访问到静态属性和方法
        Person.COUNT = 2;
        Person.show();
        
        person.COUNT = 3;
        person.show();

    }
    
}

//实体类
class Person{
    String name;//姓名
    int age;//年龄
    static int COUNT;
    
    public void eat() {}//吃
    public void sleep() {}//睡
    public static void show() {}
}
关于静态与非静态、类与对象访问的问答:
  1. 为什么可以直接通过类名调用静态的成员?

    当成员被static修饰之后就变成了静态的,会在class生成的同时放在静态方法区中一份,而静态方法区的特点是内容会随着程序的结束而释放,这里的成员已经不属于某一个实例对象,生命周期与字节码文件保持一致,大于某个实例对象,实例对象的创建与否不能影响他们的调用,可以直接使用类名调用,在用类名调用时,本质上是在使用字节码文件对象直接实现调用,这样即可以节省内存,又能提高效。

  2. 为什么不能使用类名调用非静态成员?

    使用类名调用,本质上是在使用字节码文件对象直接实现调用,字节码文件对象的出现时间要早于某个实例对象,而非静态成员的生命周期是与实例对象保持一致,所以当有字节码文件对象时,不一定有实例对象,非静态成员,所以不能调用。

  3. 静态的成员方法和非静态的成员方法优先使用哪一个?

    优先使用静态的成员方法;

    原因:静态的方法比非静态的效率高,节省内存。

    注意:但是有一种情况例外:当方法中必须使用非静态的成员变量时,必须使用非静态方法

    总结:被static修饰的成员变量会变成静态的成员变量,成员方法会变成静态的成员方法。

类是一种自定义的数据类型

  1. 类, 其实是一种自定义的引用数据类型, 这种类型可以作用于属性、方法参数、返回值…,之前怎么使用的基本数据类型, 就可以怎样使用这种类型。
  2. 注意:一个类型一旦创建出来,就是一个独立的数据类型,在他可见的范围内都是可以使用的,包括自己的内部。

this关键字

  1. 是一种引用数据类型,本身是一个关键字,用在类的实例方法或者构造方法中,代表的是当前的对象,保存的是当前对象的地址;当我们想在当前类的内部拿到当前对象的引用时,可以使用this。

  2. this的功能总结:

    • 用来区分成员变量和局部变量;
    • 可以在构造方法内部调用其他重载的构造方法,提高代码的复用性,简化代码。
    //实体类
    class Person{
        String name;//姓名
        int age;//年龄
        static int COUNT;
        
        public void setData(String name, int age) {//设置对象属性的一个方法
            //区分了成员变量和局部变量
            this.name = name;
            this.age = age;
        }
        
        public void eat() {}//吃
        public void sleep() {}//睡
        public static void show() {}
    }
    
  3. this关键字的是否省略

    • 当需要访问的属性与局部变量没有重名的时候, this关键字可以写, 也可以不写;
    • 当需要访问的属性与局部变量重名的时候, this关键字必须写, 不可以省略。
    //实体类
    class Person{
        String name;//姓名
        int age;//年龄
        static int COUNT;
        
        public void setData(String name, int nianling) {//设置对象属性的一个方法
            //区分了成员变量和局部变量
            this.name = name;//不可省略
            age = nianling;//可省略
        }
        
        public void eat() {}//吃
        public void sleep() {}//睡
        public static void show() {}
    }
    

构造方法(重)

  1. 概念:构造方法, 其实也是一个方法; 用于实例化对象, 在实例化对象的时候调用。

  2. 和普通的方法的区别:

    • 构造方法的名字,必须和类名一致;
    • 构造方法没有返回值,返回值类型部分不用写。
  3. 构造方法的意义:一般情况下,使用构造方法,是为了在实例化对象的同时,给一些属性进行初始化赋值;有参构造和无参构造说明了构造方法也是可以重载的。

    //实体类
    class Person{
        String name;//姓名
        int age;//年龄
        static int COUNT;
       	
        public Person() {//无参构造
            this.name = "";
            this.age = 18;
        }
        
        public Person(String name, int nianling) {//有参构造
            this.name = name;
            this.age = age;
        }
        
        public void eat() {}//吃
        public void sleep() {}//睡
        public static void show() {}
    }
    
  4. 构造方法的使用:

    //测试类
    public class Test5{
        public static void main(String[] args) {
            //通过无参构造实例化对象
            Person person1 = new Person();
            //通过有参构造实例化对象
            Person person2 = new Person("xiaobai", 18);
    
        }
        
    }
    
  5. 构造方法的注意事项:

    • 如果一个类中没有写构造方法, 系统会自动提供一个public权限的无参构造方法, 以便实例化对象;
    • 如果一个类中写构造方法了, 此时系统将不再提供任何的默认的构造方法;
    • 多个构造方法之间是重载的关系
  6. this在构造方法中的使用

    1. 不能自己调用自己—死循环;
    2. 不能相互调用----死循环;
    3. this充当构造方法时,必须放在第一行;
    4. this在作为方法的时候,只能充当构造方法,不能作为其他方法;
    5. this的使用范围就是当前类的内部;
    6. 只有在非静态方法中,才可以使用this。
    public class Test5 {
        public static void main(String[] args) {
            //利用系统默认的构造方法完成属性的初始化
            //当我们自己创建了构造方法后,就不会再去调用系统默认的构造方法.
            Dog dog = new Dog();
            dog.name = "拉布拉多";
            Dog dog1 = new Dog("金毛");
            System.out.println(dog1.name);
        }
    }
    
    class Dog {
        String name;
        int age;
        double height;
    
        //创建无参构造方法
        //1.一旦创建了自己的构造方法,就不会再去调用系统默认的构造方法
        public Dog() {
        //this();//自己调用自己----死循环
        //系统自动对属性进行了初始化
            System.out.println("这里是无参构造方法");
        //this("土狗");//this充当构造方法时,必须放在第一行
        }
    
        //创建有参构造方法
        //功能:在对属性初始化后,并完成赋值
        public Dog(String name) {
        //this("bing",20,2);//两个构造方法相互调用----死循环
            this.name = name;
        }
    
        public Dog(String name, int age, double height) {
        //this充当的是构造方法
            this(name);
            this.age = age;
            this.height = height;
        }
    
        public void run() {
        //这里name前面默认有个this
            name = "柯基";
            System.out.println("跑步");
        }
    }
    

代码段

构造代码段

直接在类中写的代码段, 就是构造代码段。

构造代码段中的代码, 在每次实例化对象的时候执行,执行顺序优先于构造方法.。 一般在构造方法中, 对对象的某些属性进行初始化的赋值。

构造代码段, 功能与无参构造方法是有重复的, 实际使用中, 以构造方法的使用较多。

public class Person {
    {
        System.out.println("这里就是构造代码段");
        System.out.println("实例化对象的时候执行");
        System.out.println("构造代码段的执行时机在构造方法之前");
    }
    {
        System.out.println("一个类中可以写多个构造代码段");
        System.out.println("多个构造代码段之间的执行顺序取决于书写的先后顺序");
    }
}

静态代码段

直接在类中写的代码段, 用static修饰, 就是静态代码段。

静态代码段, 当类第一次加载到内存中的时候执行, 一般进行属性的初始化赋值, 或者进行资源加载,执行顺序优先于main

public class Person {
    static {
        System.out.println("这里就是静态代码段");
        System.out.println("在类加载的时候执行");
    }
    static {
        System.out.println("一个类中可以写多个静态代码段");
        System.out.println("多个静态代码段之间的执行顺序取决于书写顺序");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值