面向对象3
1.面向对象语言的三大特征
封装:
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
封装的好处:
- 只能通过规定方法访问;
- 隐藏类的实现细节;
- 方便修改实现;
- 方便加入控制语句。
具体表现:
- 需要隐藏的信息(私有属性)使用private权限
- 为私有属性提供专门的操作和访问方法使用public权限
this关键字:
this关键字代表自身类的对象(注意:this关键字必须放在非静态方法里面)
在一个类的方法或构造方法内部,可以使用“ this.成员变量名”这样的格式来引用成员变量名,常常用来区分同名的成员变量和局部变量
package day12;
public class Person {
/*
通过访问权限修饰符private来隐藏一些信息
*/
private String name;
private int age;
/*
为隐藏的信息,提供专门的方法来操作和访问
this关键字代表自身类的对象
使用this关键字引用成员变量
使用this关键字引用成员方法
*/
public void setName(String name){
if(name.length()<5){//名字长度小于5
this.name=name;
}
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
}
继承:
继承是面对对象语言的一种设计思想。
继承是从已有的类(父类/基类)中派生出新的类(子类),新的类(子类)拥有已有类(父类/基类)的一些功能(属性和方法),并能扩展新的能力。
优点:提高代码的可重用性(子类可以使用父类的一些功能)
提高代码的可扩展性(子类可以有自己的功能)
- 在Java中使用 extends 关键字来表示继承关系。
- Java不支持多继承,单继承是Java的继承关系很简单,一个类只能有一个直接父类。
- 继承之后子类可以调用父类的所有非私有属性和非私有方法。
继承的形式:
[访问权限修饰符] [修饰符] 子类名 extends 父类名 { 子类体 }
例:
父类 Animals 如下:
package day12;
/*
父类(基类)
把动物相关的共有的属性、行为,定义在Animals类
当一个没有继承任何一个类时,jvm会默认让类继承Object类
Object是 java为所有类提供的基类(父类) 超类
*/
//public class Animals {
public class Animals extends Object {
private String name;
private int age;
public Animals() {
System.out.println("Animals类无参的构造方法");
}
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 eat(){
System.out.println("动物干饭");
}
}
子类 Dog 如下:
package day12;
/*
Dog类继承Animals类
extends关键字
Dog类是 Animals类的子类, Animals类是Dog类的父类
Dog类是 Animals类的派生类, Animals类是Dog类的基类
java中一个类只能直接继承一个类
*/
public class Dog extends Animals {
//子类扩展自己的功能
private String breed;//品种
public Dog() {
System.out.println("dog类无参的构造方法");
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
//成员方法:狗叫
public void wangwang(){
System.out.println("狗子叫");
}
}
继承的传递性:
C类从B类继承,B类又从A类继承
那么C类就具有B类和A类的所有非私有属性和非私有方法
继承中的构造方法:
- 在创建子类对象时,同时会先创建父类对象;
- 在调用子类构造方法时,先会调用父类的构造方法;
- 子类构造方法总是先调用父类构造方法,默认情况下,调用父类无参构造方法;
- 可以在子类构造方法的第一行,使用super关键字调用父类任意一个构造方法,如果用super,必须写在构造方法的第一句。
super关键字:
super关键字代表父类的引用。
用途:
- 在子类构造方法中要调用父类的构造方法,需要注意,super语句只能出现在子类构造方法体的第一句;
- 用“ super.成员变量名”来引用父类成员变量;
- 用“ super.方法名(参数列表)”的方式访问父类的方法。
- 与this的区别:this通常指代当前类,super通常指代当前类的父类。
多态:
同一种事物,在不同时刻表现不同的状态。
多态存在的三个必要条件:
- 要有继承关系;
- 要有方法重写;
- 父类引用指向子类对象。
Animals dog= new Dog();// Animals的引用指向Dog的对象
/*
编译看左边,运行期间看右边
当编译期类型是父类,运行期类型是子类时,被称为父类引用指向子类对象。
2.方法的重写(OverRide)
当子类中的成员方法的实现方式与父类中的成员方法的实现方式不同时,可以在子类中将父类中的方法重写(覆盖、复写)
前提:要有继承关系。
重写要求:
- 子类方法的结构(返回值 参数)与父类相同;
- 子类重写后的访问权限必须大于等于父类中的访问权限。
package day12;
/*
XiaoTianQuan类继承Dog类
Dog类继承Animals类
*/
public class XiaoTianQuan extends Dog {
/*
在调用子类构造方法时,先会调用父类的构造方法
*/
public XiaoTianQuan() {
// super(); 构造方法的第一行默认使用super();调用父类默认无参的构造方法
super();//如果要现实的调用,必须放在构造方法的第一行,先确保父类构造方法的调用
System.out.println("XiaoTianQuan类无参的构造方法");
}
/*
方法的重写(OverRide)
当子类中的实现方式与父类中的实现方式不同时,可以在子类中将父类中的方法重写(覆盖、复写)
super放到成员方法中,表示当前类的父类对象,在子类中可以通过super访问父类中成员
@Override 注解(类似于标签)
表示此方法是从父类中重写来的
*/
//重写eat方法
@Override
public void eat() {
System.out.println("哮天犬除了屎啥都能吃");
super.eat();
}
public static void main(String[] args) {
/*
继承的传递性:
*/
XiaoTianQuan xtq= new XiaoTianQuan();
xtq.eat();
}
}
3.类之间的关系——关联,依赖
关联关系:
对象和对象之间的连接。在java中,关联关系的代码表现形式为一个类作为另一个类的属性类型存在。
关联关系分为 单向关联 和 双向关联。
- 单向关联:A类关联B类。
- 双向关联:A类关联B类,B类关联A类。
关联关系的多重性:
- 一对一关联:一个手机号,只能有一位用户。
- 一对多关联:一位用户,可以有多个手机号。
解决一对多的关联的方案:
- 集合
- 数组
依赖关系:
指一个类A使用到了另一个类B
依赖关系的特性:
这种关系具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。
依赖与关联:
A类关联B类,指的是B类对象作为A类的属性存在。
A类依赖B类,指的是B类对象作为A类的方法参数存在。
package day12;
public class Person {
/*
通过访问权限修饰符private来隐藏一些信息
*/
private String name;
private int age;
/*
类之间的关系——关联,依赖
关联关系
对象与对象之间的连接。在java中,关联关系的代码表现形式为一个类做为另一个类的属性类型存在。
分为:单向关联 和 双向关联
关联关系的多重性:一对一关联、一对多关联
*/
//Mobile类右
private Mobile mobile;//双向关联、一对一关联
private Mobile[] mobiles;//一对多关联
/*
依赖关系
指一个类A使用到了另一个类B
*/
public void feedAnimals(Dog dog){
dog.setName("妞妞");
System.out.println("喂妞妞");
}
}
4.抽象类
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其他功能依然存在。
用abstract修饰的类就是抽象类。
抽象类不一定有抽象方法,有抽象方法,那么这个类必定是抽象类。
抽象类只能用作基类,表示的是一种继承关系。
一个类继承抽象类,要么将子类声明为抽象类,要么重写抽象类中所有的抽象方法。
抽象方法:
- 一种特殊的方法,只有定义/声明,没有实现。
- 被abstract关键字修饰,没有方法体,只是作为方法体的定义。
- 例如: public abstract void eat();//定义一个eat抽象方法
package day12.stractDemo;
/*
被 abstract修饰的类就是抽象类
抽象类不一定有抽象方法
有抽象方法,那么这个类必定是抽象类
*/
public abstract class Animals {
private String name;
public Animals() {
System.out.println("Animals");
}
/*
在顶层类中,方法的实现与子类大多不相同,南无在顶层类中可以将方法声明为抽象方法
被abstract修饰,没有方法体
只作为方法的定义
*/
public abstract void eat();
public abstract void sleep();
}