1.6面向对象
1.6.1基本概念
面向对象编程的本质
以类的方式组织代码,以对象的组织(封装)数据
抽象:面向对象是一个抽象的
三大特性
- 封装
- 继承
- 多态
从认识的角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
从代码的运行角度考虑是先有类后有对象。类是对象的模版
1.6.2对象的创建
要点:
类与对象
类是一个模版:抽象,对象是一个具体实例
方法
定义、调用!
对应的引用
引用类型 : 基本类型(8)
对象是通过引用来操作的:栈—>堆
属性:字段,成员变量
默认初始化:
数字 0、0.0;char :u0000 ; boolean : false ; 引用 : null;
定义: 修饰符 属性类型 属性名 = 属性值
类
静态的属性 属性
动态的行为 行为
package dx;
public class Demo01 {
String s1;//属性
int age;
public Demo01(String s1, int age) {//有参构造器
this.s1 = s1;
this.age = age;
}
public Demo01() {//无参构造器
}
public void shout(){//方法
System.out.println(this.s1);
}
}
/*
构造器:
1.和类名相同
2.没有返回值
作用:
1.new 本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造之后,如果想使用无参构造,要显式的定义一个无参构造函数
2.不定义任何构造器,会生成默认无参构造器
*/
package dx;
public class Demo02 {
public static void main(String[] args) {
Demo01 haha = new Demo01();//创建实例
haha.s1 = "haha";//修改属性
haha.shout();//调用类方法
}
}
1.6.3封装
该露的露,该藏的藏
程序设计追求高内聚,低耦合 即类内部数据自己操作完成不允许外部干涉,仅暴露少量方法给外部使用
封装(数据的隐藏)
属性私有 get/set
即属性的修饰符为private 外部用get /set方法来调用和修改属性
1.6.4继承
1.类的继承
继承的概念
类的继承是指在一个现有的类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类或基类,子类会自动拥有父类所有可继承的属性和方法
模版:
[修饰符] class 子类名 extends 父类名{ //核心代码 }
注意点
java中只支持单继承,不允许多重继承
可以多个类可以继承同一个父类
可以多层继承
重写父类方法
对父类的方法进行重写
要求:相同的方法名,参数列表及返回值。
super关键字
当子类重写父类方法后,子类无法直接访问父类被重写的方法,可以用super关键字来访问父类
(1) super调用父类成员变量和方法
super.成员变量 super.成员方法([参数1,参数2····])
(2)使用super关键字调用父类的构造方法
super([参数1,参数2···]) //该语句必须在子类构造函数的第一条行
子类中构造函数如果不写super调用父类构造函数则默认调用父类无参构造函数,若父类只有有参构造函数,则会出错。
Object类
所以类的父类,通常被称为超类基类或根类,当定义一个类,没有使用extends关键字,那么该类会默认继承Object类。
常用方法:
equals(Object obj) 判断某个对象与此对象是否相等
final Class<?>getClass() 返回此Object的运行时类
int hashCode() 返回该对象的哈希码值
String toString() 返回该对象的字符串表示
void finalize() 垃圾回收器调用此方法来清理没有被任何引用变量所引用对象的资源
2.final关键字
概念
final可用于修饰类,变量,方法,它有着不可更改或者最终的含义因此有以下特性
- final修饰的类不能被继承
- final修饰的方法不能被子类重写
- final修饰的变量(成员变量和局部变量)是常量,只能赋值一次
final关键字修饰类 在class前加final
final关键字修饰方法 在修饰符和返回值类型之间加final
final关键字修饰变量 在变量类型前加final
1.6.5多态
多态概述
调用父类的被覆写的方法,可以通过
super
来调用不同对象调用同一个方法时所呈现出的多种不同行为
作用:消除了类之间的耦合关系,大大提高了程序的可扩展性和维护性
java的多态性是由类的继承、方法的重写,以及父类引用指向子类对象体现的
对象的类型转换
向上转型:子类对象当作父类类型使用
把一个子类类型安全地变为父类类型的赋值,被称为向上转型
Animal an1 = new cat(); Animal an2 = new dog(); //此时不能通过父类变量去调用子类特有的方法
向下转型: 把一个父类类型强制转型为子类类型,就是向下转型。向下转型是必须转换为本质类型不然会出现错误,例如Animal类型引用指向的是一个Dog类型对象,这是进行强制类型转换为Cat类就会出现错误。
instanceof关键字
//判断一个对象是否为某个类(或接口)的实例或着子类实例 结构: 对象 (或者对象引用变量) instanceof 类(接口)
1.6.6抽象类与接口
抽象类的基本概念
如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法
class Person { public abstract void run(); }
把一个方法声明为
abstract
,表示它是一个抽象方法,本身没有实现任何方法语句。因为这个抽象方法本身是无法执行的,所以,Person
类也无法被实例化。编译器会告诉我们,无法编译Person
类,因为它包含抽象方法。必须把Person
类本身也声明为abstract
,才能正确编译它:abstract class Person { public abstract void run(); }
抽象类的注意点
- 抽象类无法被实例化只能被继承
- 抽象类的作用:为所继承的类定义规范
- 含有抽象方法的非接口类即为抽象类
接口的基本概念
如果一个抽象类没有字段,所有方法全部都是抽象方法(还可以有default方法),就可以把该抽象类改写为接口:
interface
abstract class Person { public abstract void run(); public abstract String getName(); } interface Person { void run(); String getName(); default void run() { System.out.println(getName() + " run"); } }
接口的注意点
- 接口是比抽像类更抽象的类
- 实现类可以不覆写default方法
- 接口里不允许有字段
1.6.7静态字段与静态方法
静态字段
在属性的修饰符上加static即为静态字段
class Person { public String name; public int age; // 定义静态字段number: public static int number; }
特点: 所有实例都可以修改该属性,但不建议用实例去修改
建议用 类.静态字段 去修改
静态方法
在方法前加static即为静态方法
public class Main { public static void main(String[] args) { Person.setNumber(99); System.out.println(Person.number); } } class Person { public static int number; public static void setNumber(int value) { number = value; } }
因为静态方法属于
class
而不属于实例,因此,静态方法内部,无法访问this
变量,也无法访问实例字段,它只能访问静态字段。通过实例变量也可以调用静态方法,但这只是编译器自动帮我们把实例改写成类名而已。
通常情况下,通过实例变量访问静态字段和静态方法,会得到一个编译警告。
接口的静态字段
因为
interface
是一个纯抽象类,所以它不能定义实例字段。但是,interface
是可以有静态字段的,并且静态字段必须为final
类型:public interface Person { public static final int MALE = 1; public static final int FEMALE = 2; } /*实际上,因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉,上述代码可以简写为:*/ public interface Person { // 编译器会自动加上public statc final: int MALE = 1; int FEMALE = 2; }