面向对象
**1. 面向对象的基本概念 **
1.1. 对象的基本概念
万事万物皆对象,对象具有一些特征和行为,在程序猿眼中特征就是对象的属性,行为就是对象的方法。
面向对象是一种编程思想,以对象为中心,当编程过程中某个功能是应该首先思考,是否存在特定对象,具备这样的的能力,如果有,则创建这个对象,如果没有,先定义类,然后创建对象,并使用对象
对象与对象通过某种方式产生联系:
一是方法的调用
二是属性组合的方式
1.2. 计算机中的对象
从本质上来说计算机中的对象就是内存中的一块数据区域。
1.3. 面向对象的特点
1.各司其职:利用面向对象的思想完成一个需求,可能会由多个对象共同参与。而组成系统的每个对象,其功能应该单一。就就是对象的“各司其职”
2.可重用性:对于类似的功能,不同的系统可以重复使用相同的代码。
3.可扩展性:在不修改原有系统的前提下,对系统的功能进行扩展。
4.弱耦合性:让对象和对象之间的联系尽可能的弱。
1.4. 类的概念
类是对一“类”事物的总结,可以理解为:对大量对象共性的抽象,类是客观事物在人脑中的反映。
如果定义了一个类,可以利用这个类创建多个对象。
2.类的定义
类是对象的模板,类描述一类事物的公开属性和行为
public class Dog{
//属性、方法
}
3.属性的定义
指事物的特征,以人类好盆友狗子来说,它的毛色,体重,品种……都是它的特征。
例:
public class Dog{
String maoSe;
double weight;
String pinZhong;
}
4.方法
指事物的行为,如狗子的吃喝拉撒睡,都是行为。
public class Dog{
//属性
String maoSe;
double weight;
String pinZhong;
//行为
public void eat(){
System.out.println(maoSe+"的"+weight+"kg重的的"+pinZhong+"吃狗粮");
}
public void sleep(){
System.out.println(maoSe+"的"+weight+"kg重的的"+pinZhong+"狗子睡了");
}
}
class DogTest{
public static void main(String[] args) {
Dog d1 = new Dog();
d1.maoSe = "黄色";
d1.pinZhong = "中华田园犬";
d1.weight = 60.0;
d1.eat();
d1.sleep();
}
}
5.实例化
利用类 创建对象的过程就是 实例化过程。这个对象称为类的实例。
类名 对象名 = new 类名();
Girl girl = new Girl();
6.方法重载
简单来说就是在一个类中编写方法名相同,参数个数、类型、顺序不同
一个行为可能存在不同的实现
注意与变量名无关
package com.qf.day07.ch2;
//定义计算器类
public class Calcute {
public void add(int a, int b){
System.out.println(a + b);
}
public void add(double a, double b){
System.out.println(a + b);
}
public void add(String a, String b){
System.out.println(a + b);
}
}
package com.qf.day07.ch2;
public class CalcuteTest {
public static void main(String[] args) {
Calcute cal1 = new Calcute();
cal1.add(10,20);
cal1.add(11.2,30);
cal1.add("草","是一种植物");
}
}
7.构造器
类中的特殊方法,主要用于创建对象,为属性赋初值。构造器本质也是方法
特点:
- 与方法名相同
- 没有返回值类型
- 创建对象时,触发构造器的调用,不可通过点手动调用,只能new
如果没有显示声明,系统会提供默认无参构造器
public Person(String n, int a, String s ) {
System.out.println("Person(String n, int a, String s )");
name=n;
age=a;
sex=s;
}
8.构造器的重载:
构造器本身也是方法。可以重载,为了瞒住创建对象的便利性。
在类中如果没有无参构造器,系统会自动给你提供一个,如果写了就不会提供了,所以建议不敢你用不用,无参构造器写了在说。
package ch3;
public class Person {
String name;
int age;
String sex;
//构造器
public Person() {
System.out.println("Person()");
}
public Person(String n) {
name =n;
}
public Person(String n,int a) {
System.out.println("Person(String n,int a) ");
name=n;
age=a;
}
public Person(String n, int a, String s ) {
System.out.println("Person(String n, int a, String s )");
name=n;
age=a;
sex=s;
}
// 省略其他方法
}
使用不同构造器创建对象
//使用无参构造器
Person obj = new Person();
obj.name="张飞";
obj.age=50;
obj.sex="男";
obj.show();
// 使用3数参构造器
Person obj2 = new Person("刘备", 55, "男");
obj2.show();
9.this关键字
类是模板,可服务与此类的所有对象;this是类中的默认引用,代表当前实例;当类服务于某个对象时,this指向这个对象
区别实例变量和局部变量;
this : 本质是一个引用,当前对象的引用,谁调用就是谁
- 作为引用 可区分 实例变量和成员变量
class A{
String name;
public A(String name){
this.name=name
}
}
- 调用本类中其他构造器
class A{
String name;
int age;
public A(String name){
this.name=name
}
public A(String name,int age){
this(name);//调用A(String name)构造器
this.age=age;
}
}
this(name) 需要在构造器的第一行
10.自定义类型
我们编写的类,可以完全理解为一个数据类型,就和java其他数据类型一样,可以作为 参数类型 返回值类型 数组类型,同时自定义类属于 引用数据类型。引用数据类型存储分为堆栈存储,对象存在堆区, 对象的引用存在栈区。栈里面存的是对象的地址。
例:
//武器类
public class Weapon {
String name;
int actPower;
public Weapon() {
}
public Weapon(String name,int actPower) {
this.name = name;
this.actPower=actPower;
}
}
面向对象三大特性
封装
隐藏细节部分,提供统一访问方法,从而控制对属性方法的访问。
关键:private
通过在属性和方法前添加 private 关键字
效果:出了本类后无法直接 对象.属性。
封装方法
package ch3;
/**
* 封装:隐藏内部细节,提供统一访问方法。
* 1. 赋值: setXXX( 参数 )
* 2. 取值: getXXX():返回值
*
* @author Y7000
*
*/
public class Girl {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println(this.name+":"+this.age);
drawFace();
}
//什么样的方法定义为私有呢?
// 一般不独立工作的方法,配合其他方法完成功能。
private void drawFace() {
System.out.println("上颜料......");
}
}
继承
程序中的继承,是类与类之间特征和行为的赠与与获得
两个类之间的继承关系,必须满足"is a"的关系
多个类别都可以作为“狗”的父类,需要从中选出最适合的父类
实战:可根据程序需要使用的多个具体类,进行共性抽取,进而定义父类
继承语法:
class 字类 extends 父类{
}
继承的特点:
Java为但继承一个类只能有一个直接父类,但可以多级继承,属性和方法逐级叠加
继承的作用:
减少冗余代码,实现代码复用,思路就是吧各个类的公共属性和行为定义在父类身上,字类通过建立继承关系,从而获得这些属性方法
不能继承的
- 构造方法
- private修饰的属性和方法不能继承
- 被default修饰过的属性和方法,在父子类跨包的情况下不能继承
属性的定义
public class Dog exctends Animal{
public Dog(){
}
public Dog(String name,int weight,String color){
this.name = nname;
this.weight = weight;
this.color = color;
}
}
访问修饰符:
修饰符 | 本类 | 同包 | 非同包子类 | 其他 |
---|---|---|---|---|
private | OK | NO | NO | NO |
default | OK | OK | NO | NO |
protected | OK | OK | OK | NO |
public | OK | OK | OK | OK |
注意:从上到下,从严到宽。
方法的重写
子类从父类继承到的方法不能满足自身要求,那么字类可以将对方的实现逻辑重新实现
- 保证方法的签名一致 返回值 方法名(参数列表)
- 访问权限不能更严
- 不能抛出比父类更宽泛(大)的异常
重写方法验证:
- 使用注解@@Override,检查是否满足重写方法的条件
Super关键字
是一个引用,指向父类的引用,执行父类对象,利用引用可以实现
区分 子类 与父类的属性和方法。
调用 父类的构造器。
注意:
子类创建的过程如果父子类关系,创建字类对象时,先创建父类对象(因为子类继承来的那部分属性的空间,需要利用一个父类对象来开辟)。一个完整的字类对象的空间因该是两部分构成。
多态
父类类型的引用可以指向子类对象。
父类名 对象名 = new 子类名();
父类名 对象名 = new 子类名();
父类的引用仅可调用父类所声明的属性和方法,不可调用子类独有的属性和方法
多态中的应用场景
父类类型作为参数,可以兼容各种子类类型的参数
父类类型作为返回值,可以返回各种子类类型的返回值
多态中的方法重写
why(为什么重写):父类的方法满足不了子类的需求,在子类中重写父类的方法
注意:
重写方法签名和参数类型、顺序、数量要与原方法保持一致,与返回值无关
例:
package com.qf.day10.t2;
//交通工具
public abstract class Transportation {
private String name;
public Transportation() {
}
public Transportation(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void transport(String name);
}
package com.qf.day10.t2;
public class Car extends Transportation {
public Car() {
}
public Car(String name) {
super(name);
}
@Override
public void transport(String name) {
System.out.println(name);
}
}
向上转型/向下转型
向上转型:
父类引用中保存真实的子类对象
Animal animal = new Dog();
注意:
仅可调用父类的属性和方法
向下转型;
将父类应用中的子类对象对象,强转回子类本身的类型
Dog dog = (Dog) animal;
instanceof关键字
向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性
语法: 父类引用instanceof类型 //返回Boolean类型结果
public class TestStart {
public static void main(String[] args) {
Start start1 = new Sports();
start1.setName("邓超");
String sname1 = start1.getName();
start1.setSex("男");
String sex1 = start1.getSex();
start1.setNationality("中国");
String nationality1 = start1.getNationality();
start1.setAge("30");
String age1 = start1.getAge();
if(start1 instanceof Sports){
Sports sports = (Sports) start1;
sports.setJob("环保卫士");
String job = sports.getJob();
sports.setTalent("rap");
String talent1 = sports.getTalent();
sports.performance();
sports.introduction();
}
多态使用场景
使用父类方法作为形参,实现多态
调用方法时,可以传递实参类型包括:本类型对象+其所有的子类对象
使用父类方法作为返回值,实现多态
调用方法后,可以传递结果类型包括:本类型对象+其所有的子类对象
使用父类类型作为数组,保存对象