Java篇8--面向对象

一、面向对象简介

1. 面向对象是什么

OOP:Object Oriented Programming
面向对象是一种程序的设计范型,是一种思想,使用 对象 的概念进行程序设计
一切皆对象,世间万物都是对象

2. 两个概念

2.1 类

类是具有相同的特征和行为的一组对象的抽象
类是一个抽象的概念,没有具体事物与之对应,如人类、动物等

2.2 对象

对象是类的实例
对象是某一个具体的事物,如这个学生、这只狗

3. 产生

二、类的使用

1. 定义类

语法:

class 类名 { 
	//成员属性; 
	//成员方法; 
}

类:

  • 一个类就是一个数据类型,定义一个类其实就是创建了一个数据类型
  • 类名使用帕斯卡命名法,即所有单词首字母大写
  • 一个文件中可以定义多个类,但只能有一个public修饰的类,且此类的名称必须与文件名相同
    实际开发中都是一个类对应一个文件,不允许一个类中对应多个文件

属性:

  • 类的特征
  • 定义方式: 数据类型 属性名;
  • 属性名使用驼峰命名法,即第一个单词首字母小写,其他单词首字母大写

方法:

  • 类的行为
  • 定义方式: public 返回值类型 方法名(参数列表){ 方法体}
  • 方法名使用驼峰命名法,且一般多使用动词
public class Test08_Car {
	//属性
	String name;
	String color;
	String direction;
	int speed;
	double price;
}

2. 创建对象

语法:

//		方式1 
		类名 对象名=new 类名(); 
//		方式2 
		类名 对象名; 
		对象名=new 类名();

3. 访问对象

访问对象的属性: 对象名.属性名
访问对象的方法: 对象名.方法名()

		Test08_Car aCar = new Test08_Car();
		aCar.name="北京现代";
		aCar.color="white";
		aCar.direction = "west";
		aCar.speed = 20;
		aCar.price = 13.5;
		System.out.println(aCar.name);
		System.out.println(aCar.color);

三、this关键字

1. 全局变量和局部变量

全局变量:

  • 在类中定义的变量,称为全局变量,也就是属性
  • 在整个类中都可以使用
  • 有默认值,可以直接使用

局部变量:

  • 除全局变量以外的其他变量,称为局部变量,如在方法 或 代码块中定义的变量
  • 只能在局部访问
  • 没有默认值,必须先赋值才能使用
  • 局部变量和全局变量同名,局部变量优先级更高,即默认访问的是局部变量

可以使用this关键字来解决局部变量和全局变量同名的问题

2. this用法

this表示当前类的一个对象

  • 只能在类的方法中使用,表示方法的调用者,即调用该方法的对象
  • 当局部变量和全局变量同名时,可以使用 this. 来访问全局变量
  • 当局部变量和全局变量不同名时,可以省略不写 this.
public class thisExs {
	
	public static void main(String[] args) {
		Account account = new Account();
		account.querymoney();//引用数据类型的默认值是null,基本数据类型的默认值是他的缺省值
		account.getMoney();
	}
}
/*
 * 账户类
 */
class Account{
	/*
	 * 全局变量
	 */
	String name="tom";
	double money;
	
	
	//查询余额
	public void querymoney() {
		System.out.println("姓名:"+name+",余额:"+money);
	}
	
	//存钱
	public void savemoney(double money) {
		this.money+=money;
	}
	
	public void getMoney() {
		int a = 5;//局部变量
		System.out.println(a);
		String name = "alice";
		System.out.println(this.name);
	}
}

四、static关键字

static表示静态的,可以用来修饰变量和方法,分别称为静态变量和静态方法

1. 静态变量

使用static修饰的变量,称为静态变量 或 类变量(非static修饰的变量称为实例变量)
静态变量为类的所有对象所共有,属于整个类
访问方式: 对象名.属性名类名.属性名 (推荐)

2. 静态方法

使用static修饰的方法,称为静态方法 或 类方法(非static修饰的方法称为实例方法)
访问方式: 对象名.方法名()类名.方法名() (推荐)
静态方法中只能访问静态变量或静态方法,不能访问实例变量和实例方法 ;实例方法中可以访问静态方法
变量分类:

  • 从作用域上划分:全局变量、局部变量
  • 从变量所属上划分:实例变量、类变量
public class staticExs {
	
	public static void main(String[] args) {
		Student stu1 = new Student();
		stu1.name = "tom";
		Student.hobby="soccer";//推荐
		
		Student stu2 = new Student();
		stu2.name = "tom";
		stu2.hobby = "basketball";
		
		System.out.println(stu1.name);
		System.out.println(Student.hobby);
		Student.f1();
	}
}

/*
 * 学生类
 */
class Student{
	String name;
	static String hobby;
	double money;
	
	public static void f1() {
		System.out.println("111");
	}
}

五、方法重载

一个类中包含两个或两个以上同名的方法,其参数不同,称为方法重载overload

  • 在同一个类中
  • 方法名相同
  • 参数列表不同(参数个数、类型、顺序至少有一项不同),即方法签名不同
  • 与方法修饰符、返回值类型、形参名无关

作用:提供同一种功能的多种实现方式,根据调用者传递的参数来决定采用哪种方式

public class overLoadExs {
	
	public static void main(String[] args) {
		Caculator c = new Caculator();
		//调用时会根据传递参数的不同调用相应的重载方法
		System.out.println(c.sum(1,2));
		System.out.println(c.sum(1, 2, 3));
		System.out.println(c.sum(1.1, 2.2));
	}	
}

/*
 * 计算器类
 */
class Caculator{
	
	public int sum(int num1,int num2) {
		return num1+num2;
	}
	public  int sum(int num1,int num2,int num3) {
		return num3+sum(num1, num2);
	}
	public double sum(double num1,double num2) {
		return num1+num2;
	}
	public double sum(double num1,double num2,double num3) {
		return num3+sum(num1, num2);
	}
}

练习:对象数组 :创建一个元素是对象的数组并使用
在这里插入图片描述

	/*
	 * 写一个方法,用来录入车辆信息
	 */
	public static void inputInfo(Car[] cars) {
		
		Scanner inScanner = new Scanner(System.in);
		for (int i = 0; i < cars.length; i++) {
			cars[i] = new Car();//java.lang.NullPointerException,不new一个对象,会报空指针异常
			System.out.println("请录入第"+(i+1)+"辆车的名称:");
			cars[i].name = inScanner.next();
			System.out.println("请录入第"+(i+1)+"辆车的颜色:");
			cars[i].color = inScanner.next();
			System.out.println("请录入第"+(i+1)+"辆车行驶的速度:");
			cars[i].speed = inScanner.nextInt();
		}
	}

六、构造方法

构造方法是一种特殊的方法,也称为构造函数 或 构造器 constructor
作用:用于创建和初始化对象
特点:

  • 方法名必须和类名相同
  • 没有返回值,也不能写作void
  • 当创建类的对象时,会自动调用构造方法
  • 一个类中可以有多个构造方法(构造方法重载)
  • 如果没有自定义构造方法,则类中默认会有一个无参的构造方法
  • 如果自定义了构造方法,则默认的无参构造方法就没有了,可以自己写无参的构造方法(建议)
  • 可以使用 this(参数) 调用当前类中的另一个构造方法,但只能出现在构造方法的第一行
	//构造方法
	public Dog() {
		System.out.println("无参的构造方法........");
	}
	
	public Dog(String name,int age) {	
		this();//调用构造方法
		System.out.println("带两个参数的构造方法........");
		this.name = name;
		this.age = age;
	}
	
	public Dog(String name,int age,String breed) {	
		this(name,age);//调用构造方法
		System.out.println("带三个参数的构造方法........");
		this.breed = breed;
	}

七、包package

包的作用:

  • 区分同名的类
  • 类较多时便于管理
  • 便于访问控制

声明包:

  • 用来指定当前类所在包
  • 使用package,写法: package 包名;
  • 必须位于第一行(注释除外)

命名规范:

  • 采用组织的反向域名
  • 使用小写字母,不能以点号开头或结尾
  • com.baidu.fanyi

导入包:

  • 当需要使用其他包中的类时必须导入
  • 使用import,写法: import 包名.类名;import 包名.*;
  • 必须位于包声明的下面

常用的包:

  • java.lang 包含Java的核心类,如System、String、Math等,该包默认会被自动导入,当使用其中的类,无需import导入
  • java.util 包含实用的工具类,如Scanner、Arrays等
  • java.io 包含输入/输出操作的类
  • java.sql 包含数据库操作的类
  • java.net 包含网络操作的类
  • java.awt 包含图形窗口操作的类

注意:定义类务必指定包名,严禁将类直接放到src下(default package默认包),会导致类无法被引用

八、访问修饰符

用来控制访问范围,可以修饰属性、方法、类等

修饰符同一个类同一个包内的类不同包的子类不同包且不是子类
public公开的
protected受保护的
default默认
private私有的

总结:

  • public:在哪都能访问
  • protected:只有不同包并且非子类不能访问,其他都能访问
  • 默认:只有本包中可以访问
  • private:只有本类中可以访问

范围从大到小的顺序:public>protected>默认>private

九、对象的初始化顺序

1. 类加载

概念:将class文件读取加载到JVM内存中的过程,称为类加载
类加载的时机:

  1. 创建类的对象
  2. 调用类的静态属性或静态方法
  3. 执行main方法时,main方法所在的类会被加载
  4. 通过反射调用类 Class.forName("包名.类名")

2. 类的成员

类中的成员:

  • 属性(实例属性、静态属性)
  • 方法(实例方法、静态方法)
  • 构造方法
  • 代码块
  • 静态代码块:使用static修饰的代码块

注:static关键字可以修饰变量、方法、代码块、匿名类等

3. 初始化顺序

步骤:

  1. 对象所在的类被加载
    执行静态属性和静态代码块(根据定义的顺序,从上往下执行)
    特性:
    • 静态变量在类加载时初始化,且在内存中只分配一块空间
    • 静态代码块在类加载时执行,且只执行一次(类只会被加载一次),主要用于初始化静态属性
    • 静态代码块中不能初始化实例变量,只能初始化静态变量
  2. 对象被创建
    执行实例属性和代码块(根据定义的顺序,从上往下执行)
    执行构造方法

总结:执行先后顺序: 静态代码块>代码块>构造方法 其中静态代码块和静态变量没有初始化先后顺序,看定义的先后顺序

十、面向对象的三大特征

1. 封装

1.1 Java代码规范
  • 将类的属性封装在类中,不允许在类的外部直接访问,保护数据的安全,使内容可控
  • 只能通过被授权的方法才能对数据进行访问
  • 类的基本原则就是封装
1.2 实现方式

步骤:
1、将属性私有化
使用private修饰属性
2、提供对外访问的方法,用于赋值、取值
使用public修饰方法
方法的命名规范:

  • 赋值方法:以set开头,后面属性名,如setXxx,称为setter方法(属性名首字母大写)
  • 取值方法:以get开头,后面属性名,如getXxx
  • 如果是boolean类型属性,可以getXxx,也可以是isXxx

如果属性只具有getter方法,则表示该属性是只读的,在外部只能读取
如果属性只具有setter方法,则表示该属性是只写的,在外部只能修改

快捷生成方式:右键-->source-->Generate Getters and Setters

2. 继承

2.1 概念

可以让一个类继承自另一个类,此时该类会继承另一个类中的属性和方法
继承而得到的类称为子类,被继承的类称为父类(超类/基类)
继承是一种 is a 的关系,比如: cat is a animalstudent is a person

2.2 实现方式

语法:

class 子类 extends 父类{
	//代码块
} 

作用:

  • 代码复用:将多个子类中相同的属性和方法放到父类中
  • 功能扩展:子类可以有自己独特的属性和方法

特性:

  • Java只支持单继承,不支持多继承,但支持多层继承,即继承的传递
  • Java中所有的类都直接或间接的继承了java.lang.Object类(后面会详细讲),如果不显示写extends某个类,都默认继承Object类
/*
 * 学生类
 */
class Students{
	String name;
	int age;
	String sex;
	
	public Students() {
		
	}
	
	public Students(String name,int age,String sex) {
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
	public void show() {
		System.out.println("我是一个学生,姓名:"+name+",年龄:"+age+",性别:"+sex);
	}
}

/*
 * 小学生类
 */
class Pupil extends Students{
	String cartoon;//动画片
	
	public Pupil() {
		
	}
	
	public Pupil(String name,int age,String sex,String cartoon) {
		super(name,age,sex);
		this.cartoon = cartoon;
	}
	
	public void watch() {
		System.out.println("正在看动画片:"+cartoon);
	}
}
2.3 继承的范围

子类可以继承父类的哪些成员?

  • 父类的public、protected、默认修饰的属性和方法可以被子类继承(同包的情况下
  • 父类的private修饰的属性和方法不能被子类继承
  • 父类的构造方法不能被子类继承(构造方法名必须与类名相同,而子类名称不可能与父类相同)
2.4 构造方法的调用

调用过程:

  • 创建子类对象时默认会自动调用父类无参的构造方法(此时必须要保证父类中有无参构造,否则会报错)
  • 从子类开始,逐层往上调用父类的构造方法,直到Object类,然后再层层返回到子类中,执行后续代码
  • 创建子类对象时必须会调用父类的构造方法,而调用父类构造方法也就创建了父类的对象,所以当创建子类对象时,其实也创建了父类对象,只不过这个父类对象并不是独立存在的,而是和子类对象合为一个整体
    在这里插入图片描述
    super关键字:
  • 表示父类对象的引用,只能在子类中使用
  • 可以使用 super() 调用父类的构造方法,必须位于第一行
  • 可以使用 super. 访问父类的属性和方法,解决父类和子类中成员同名的问题

this关键字:

  • 表示当前对象的引用,只能在方法中使用
  • 可以使用 this() 访问当前类中重载的构造方法,必须位于第一行
  • 可以使用 this. 访问本类中的属性和方法,解决全局变量和局部变量同名的变量

注:调用构造方法时this()和super()都只能放在第一行,所以不能同时使用

2.5 方法重写

子类中的方法,与父类中的方法的名称、参数列表、返回类型一样,我们就说子类重写了父类的方法,称为方法重写OverRide

  • 在父子类中
  • 方法名相同
  • 参数列表相同
  • 返回类型相同或是子类
  • 访问修饰符不能缩小,即访问权限不能缩小
  • 子类不能抛出比父类更大的异常(后面会详细讲)

作用:用来重新定义子类的行为,解决父类和子类的差异性
面试:方法重载和方法重写的区别

3. 多态

3.1 概念

多态是具有表现多种形态的能力的特殊,即一种事物,具有多种形态
回顾?基本数据类型之间的转换

  • 自动类型转换
  • 强制类型转换

引用类型之间的转换

3.2 引用类型之间的转换

两种:

  • 自动类型转换
    将子类对象转换父类,如student——>Person
    将父类的引用指向子类的对象,称为向上转型,会自动进行类型转换
    特性:

    通过父类引用变量调用的方法是子类重写后的方法,不是父类的方法 通过父类引用变量无法访问子类特有的属性和方法

  • 强制类型转换
    将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,必须进行强制类型转换
    语法: (子类类型)指向子类对象的父类引用
    特性:

    向下转型后,可以访问子类特有的属性和方法 必须转换为父类指向的真实子类类型,否则会出现类型转换异常ClassCastException
    向下转型是不安全的,可以在转换时使用 instanceof 操作符判断对象的类型,避免类型转换异常

		if (person1 instanceof Doctor) { //判断一个对象是否属于某个类或者实现某个接口,结果为true执行
			Doctor doctor = (Doctor)person1;
			doctor.hospital = "No.1";
			doctor.operate();			
		}
3.3 多态的实现

将父类作为方法形参,将子类的对象作为方法实参,从而实现多态
案例:主人与宠物、玩耍、喂养

  • 主人类 Master
  • 宠物 Pet ——> Dog、Cat…
  • 食物 Food——>Bone、Fish…
3.4 总结

实现多态的条件:

  • 继承的存在(继承是多态的基础,没有继承就没有多态)
  • 子类重写父类的方法(多态下调用的是子类重写后的方法)
  • 父类引用变量指向子类对象(向上转型)

多态的优点:

  • 减少代码量
  • 提高可扩展性和可维护性
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值