JAVA面向对象

5. 面向对象

Idea查询类的方法快捷键:在类上放置光标,按住Ctrl点击

Idea查询类的继承关系快捷键:Ctrl+H

面向对象的三大特征【封装、继承、多态】

在开发过程中,考虑怎样传参以及怎样设计远比具体的实现操作重要得多。

设计类切忌完整繁杂,而应该尽可能的分化成方法和接口。

5.1 面向对象的简介

面向过程

是一种看待问题,解决问题的思维方式。着眼点在于问题是怎样一步步解决的,然后亲历亲为解决问题。

面向对象

是一种看待问题,解决问题的思维方式。着眼点在于找到一个可以解决问题的实体,委托其帮助解决问题。

**NullPointerException 产生原因:**使用了一个null进行地址访问。这里的null表示该对象中没有存储任何的地址。

5.2 类的设计与对象的实例化

对象:可以帮助解决问题的实体。

:由若干具有相同特征、行为的对象组成的集合。

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

类和对象的关系:类是对象的集合,对象是类的个体。

备注:在程序设计中一定是先有类后有对象

5.2.1类的设计

语法

[访问权限修饰符] class 类名{
    // 类体
 	// 使⽤属性,来描述所有的对象共有的特征
 	// 属性,其实就是⼀个变量
    // 使⽤⽅法,来描述所有的对象共有的⾏为
}

语法说明:

1.类名:是一个标识符,遵循大驼峰命名法
2.特征:又叫属性,在类中体现为全局变量(决定该类在建立对象时在堆上开辟的内存空间大小)。
3.行为:在类中的体现是方法(不会在堆上开辟内存空间,存在于方法区)。

实例化一个Dog类:

public class Dog{
    //类中可以写属性和行为,统称为这个类的成员
    String name;		//狗对象的名字
    String color;		//狗对象的颜色
    int age;			//狗对象的年龄
    static int count;
    //以下三个方法都是描述一个狗对象的功能
    void eat(){
        System.out.println("狗会吃");
    }
    void sleep(){
        System.out.println("狗会睡觉");
    }
    void beat(){
        System.out.println("狗会打豆豆");
    }
    static void show(){
        System.out.println("狗会秀");
    }
}

特殊说明:

1、关于属性:属性,其实就是⼀个变量,最好不要使⽤⼀个类型,多个标识符的⽅式定义。
2、关于属性:类中的属性,不是局部变量,是有默认值的。
 整型:0
 浮点型:0.0
 布尔型:false
 字符型:'\0' -> 空格
 引⽤数据类型:null
3、关于⽅法:类中,绝⼤部分的⽅法,都不⽤static修饰。
5.2.2对象的实例化

本质:在堆上开辟内存空间并分配给各属性,并将地址赋给对象。

用到关键字new,也就是说类是一种自定义的引用数据类型。

实例化一个Dog对象:

Dog xiaoming = new Dog();

注:在使用类成员的时候,要确保该类以及该类的内部类都已经实例化。

5.3 构造方法

快捷键:Alt+Insert

作为生命周期中的第一个方法,一般会在构造方法中,对对象的某些属性进行初始化赋值操作。

5.3.1 与普通方法的区别:
  1. 构造方法除了访问权限修饰符无其他修饰符
  2. 构造方法无返回值,不要写返回值 void 这部分。
  3. 构造方法名必须与类名相同
  4. 构造方法不能被显式调用,在实例化一个对象时被自动调用。

例:

//构造方法的声明
public class Person {
     /**
     * ⽆参构造
     */
     Person() {
     System.out.println("⽆参的构造⽅法执⾏了");
     }

     /**
     * 有参构造
     */
     Person(String name) {
     System.out.println("有参的构造⽅法执⾏了");
     } 
}

//构造方法的调用
// 通过⽆参的构造⽅法,实例化了⼀个Person对象
Person xiaoming = new Person();
// 通过有参的构造⽅法,实例化了⼀个Person对象
Person xiaobai = new Person("xiaobai");
5.3.2 构造方法默认的提供援助
  1. 若一个类中未写任何构造方法,此时该类中会包含一个系统提供的public权限无参构造方法。
  2. 若一个类中写了构造方法,此时系统不再提供任何构造方法。

构造方法可以重载,通过参数区分。

5.3.3 构造方法中调用其他的构造方法:

在构造⽅法中,是希望给某些属性进⾏初始化的赋值操作。⼀个类中可能写了多个构造⽅法,每⼀个

构造⽅法,都为指定的属性进⾏了初始化的赋值。但是在不同的构造⽅法中,可能会存在重复的赋值部分。因此构造方法间可以相互调用以减少冗余,此时使用this()可以调用其他构造方法以减少冗余(通过参数区分调用不同构造方法)。

// 调⽤当前类中其他的构造⽅法:
// 使⽤关键字 this() 来调⽤当前类中的构造⽅法。
Person(String name, int age, char gender) {
     this.name = name;
     this.age = age;
     this.gender = gender; 
}
Person(String name, int age, char gender, int height, int weight) {
     // 调⽤当前类的构造⽅法
     this(name, age, gender);
     this.height = height;
     this.weight = weight; 
}

注意事项:

1、在调⽤构造⽅法的时候,this()语句必须在第⼀⾏,前⾯不能加任何的语句。

2、在进⾏构造⽅法的调⽤的时候,不要出现循环调⽤。

5.3.4【拓展】析构方法 finalize

java中存在GC:garbage Collector(垃圾收集器),可以定时检测是否有废弃的空间并清理掉。

析构⽅法,是对象的⽣命周期中最后的⼀个⽅法。执⾏时机是当这个对象被销毁之前。执行了这个⽅法

之后,空间就会被销毁,这个对象也就不存在了。

@Override
protected void finalize() throws Throwable {
 	super.finalize();
}

每⼀个类的析构⽅法,都是finalize。在析构方法中,常常做的是对这个类所占⽤的资源进⾏释放。例

如:IO流的关闭、数据库连接的断开。。。

⾯试题:简述 final、finally、finalize 的区别

final: 修饰变量,表示常量;修饰类,表示最终类,⽆法被继承。修饰⽅法,表示最终⽅法,⽆法

被重写。

finally: 是异常捕获中的最后⼀个环节,⽆论try中的代码是否有异常,finally中的代码始终会执

⾏。⼀般在finally中也是进⾏的资源的释放操作。

finalize: 是⼀个类中的析构⽅法,表示对象即将被销毁。

5.3.5【拓展】构造代码段

直接写在⼀个类中的代码段,并且,这个代码段没有使⽤static修饰,就是⼀个构造代码段。构造代码

段,其实才是⼀个对象⽣命周期的开始,执⾏是在构造⽅法之前的。

public class Dog {
 String name;
 int age;
     {
     	// 构造代码段,可以写多个
     	// 多个代码段的执⾏时机,跟书写的先后顺序是有关的
     	System.out.println("构造代码段2执⾏了");
     }
     {
     	// 这⾥就是⼀个代码段,因为这个代码段直接写在了类中,⽽且没有加static修饰
     	// 这样的代码段就是⼀个构造代码段
     	// 每次实例化对象的时候执⾏,且早于构造⽅法
     	System.out.println("构造代码段1执⾏了");
     }
     	public Dog() {
     	System.out.println("Dog类的⽆参构造⽅法执⾏了");
     }
     	public Dog(String name, int age) {
     	System.out.println("Dog类的有参构造⽅法执⾏了");
     	this.name = name;
     	this.age = age;
     }
}
5.3.6 属性的赋值规范

在类的属性赋初始值的时候,如果不需要在构造⽅法中赋值,⾮静态的属性,应该在⽆参构造⽅法中赋

初始值;静态的属性应该在静态代码段中赋初始值。

// 规范
class Person {
     String name;
     int age;
     static int count;
     Person() {
     this.name = "xiaoming";
     this.age = 10;
     }
     static {
     count = 10;
     }
}
5.4 成员访问

访问类中的成员(属性、方法),使用点语法来访问。

类名.属性;
类名.方法;
5.4.1成员分类

类中的成员大致可以分两种:静态成员、非静态成员

5.4.2非静态成员

没有使用关键字 static 的成员均为非静态成员,也叫做实例成员。

非静态的成员是属于对象的,在访问时需用对象来使用,由此非静态成员也叫做实例成员。

5.4.3静态成员

使用关键字 static 修饰的成员,属于类,在访问时需用类来使用,也称 类的成员。

其实静态成员也可以用对象访问,但不推荐

5.4.4静态成员与非静态成员的内存分析

1.非静态属性:空间的开辟发生在实例对象时。

非静态属性的空间,在堆空间中,随着对象的实例而开辟,随着对象的销毁而销毁。

2.静态属性:空间的开辟,是发生在第一次被加载到Java内存(当程序第一次使用到该类时)。

静态属性的空间,是在静态空间中,随类的加载被开辟,程序执行过程中,不会销毁,常驻内存。

注意:在非静态方法中,可以调用非静态和静态成员(规则上不允许对象调用静态成员)。而在静态方法中只能直接访问静态成员。

​ 在绝大多数情况下,属性、方法、类需要被定义为非静态类型,除非某属性需要被所有对象共享,可以设置静态属性。

5.4.5【拓展】静态代码段

其实也是⼀个代码段,只不过这个代码段⽤static修饰了。重要程度⾼于构造代码段。

1、执⾏时机:

静态代码段,属于类的。当类第⼀次被加载到内存中的时候执⾏且仅执行一次,执行顺序在构造代码段之前。即第⼀次在程序中⽤到这个类的时

候。例如:实例化对象、调⽤静态的⽅法、访问静态的属性、Class.forName(反射)

静态代码段加载到内存的时机:

  1. 实例化一个对象。
  2. 使用类访问静态成员(包括静态属性、静态方法)。
  3. Class.forname。

2、访问

因为代码段是静态的,只能直接访问当前类中的静态成员,不能直接访问⾮静态成员。参考静态⽅法。

public class Dog {
     String name;
     int age;
     static int count;
     static {
     	// 静态代码段
     	System.out.println("静态代码段执⾏了");
     }
     {
     	// 构造代码段,可以写多个
     	// 多个代码段的执⾏时机,跟书写的先后顺序是有关的
     	System.out.println("构造代码段2执⾏了");
     }
     {
     	// 这⾥就是⼀个代码段,因为这个代码段直接写在了类中,⽽且没有加static修饰
     	// 这样的代码段就是⼀个构造代码段
     	// 每次实例化对象的时候执⾏,且早于构造⽅法
     	System.out.println("构造代码段1执⾏了");
     }
     	public Dog() {
     	System.out.println("Dog类的⽆参构造⽅法执⾏了");
     } 
}
5.5 包 Package

起到组织代码、组织文件的作用,类似于文件夹

Package:声明当前文件属于哪一个包,为了给编译后的.class文件找路径。

5.5.1 包的基本结构

包与包之间,以进⾏分隔。包名在命名的时候,是⼀个标识符,遵循⼩驼峰命名的规范。

5.5.2 不同包中的类如何使⽤

注:在Java中存在许多同名的类,一定要注意所使用的类来自于哪个包!

一个类中若需使用其他包的类,有两种方式:

  1. 使用类的全限定名:从这个包的最外层开始,例:

    com.epackage.Person xiaoming = new com.epackage.Person();
    
  2. 导包(主要方式):使用关键字 import添加指定的包(类)。

    例1:

    import com.epackage.Person;		//导入指定类
    

    例2(尽量不要用.*):

    import com.epackage.*;		//导入指定包下的所有类,注意不能导入其子包的类
    

    注:如果导⼊的多个包中有同名的类,或者导⼊的包和当前包中有同名的类,此时如果想区分这些类,

    只能通过全限定名区分。

  3. 如果导入的保重含有存在歧义的类,必须使用全限定名。

5.6 this关键字

this可以用在非静态方法、非静态代码段和构造方法中。

在一个类的方法中,允许参数名字与属性的名字重复。因为属性的空间开辟在堆上,而参数作为局部变量,空间开辟在栈中。该情况下在方法中直接写变量的名字,使用的是 参数而非属性。

this表示对当前对象的引用。

1.若用在一个非静态方法中,代表调用该方法的实例对象。
2.在构造方法中,this表示刚刚被实例化的对象。
3.不产生歧义的情况下可以适当省略this。

在一个类中,在访问当前属性和方法中,在某些情况下(省略this不会产生歧义) this 可省略。

例:

public class Person {
     String name;
     int age;
     char gender;
     int height;
     int weight;

     void setInfo(String name, int age, char gender, int height, int weight) {
     this.name = name;
     this.age = age;
     this.gender = gender;
     this.height = height;
     this.weight = weight;
     } 
}

this()调用当前类中的其他构造方法

在构造方法中,可以使用this()调用当前类中的其他的构造方法,具体调用哪一个构造方法,由小括号中的实参来区分。

以此法调用其他构造方法时注意事项

1.这一句话必须写在构造方法中的第一行。

2.不要循环调用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值