面向对象的三大特征:继承性、封装性、多态性
继承性
- 关键字:extends
概念
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。[1] Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。比如可以先定义一个类叫车,车有以下属性:车体大小,颜色,方向盘,轮胎,而又由车这个类派生出轿车和卡车两个类,为轿车添加一个小后备箱,而为卡车添加一个大货箱。
eg:
- 定义一个Father类 作为父类
package com.object;
/**
* 面向对象:继承
* 定义一个Father类
* @author LingDu
*/
public class Father {
int money = 100000000;
String sex = "男";
}
- 定义一个子类:Son类 继承父类Father类
package com.object;
/**
* 定义一个Son类,继承Father类
* 继承关键词:extends
* @author LingDu
*
*/
public class Son extends Father{
//定义一个money表示自己的钱
int money = 100;
//从Father类继承money
public int getMoneyFromFather() {
return super.money;
}
public static void main(String[] args) {
//创建一个对象
Son lingdu = new Son();
System.out.println("自己的钱:" + lingdu.money);
System.out.println("继承父亲的财产之后:" + lingdu.getMoneyFromFather());
}
}
封装性
概念
- 封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节
/**
* 定义一个父类Aminal
* @author LingDu
*
*/
public class Animal {
//定义一个私有类型的变量
private String name;
//只能通过set方法设置名字
public void setName(String name) {
this.name = name;
}
//输出名字
@Override
public String toString() {
return "动物的名字叫:" + name;
}
}
public static void main(String[] args) {
Animal dog = new Animal();
dog.setName("哈士奇");
System.out.println(dog.toString());
Animal bird = new Animal();
bird.setName("画眉鸟");
System.out.println(bird.toString());
}
特性
- 1、把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象)。
- 2、信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系。
多态性
概念
对象的多态性是指在一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或服务在一般类及其各个特殊类中具有不同的语义
- 定义一个Person抽象类
/**
* 多态性
* 多态存在的三个必要条件
* 1:要有继承
* 2:要有重写
* 3:父类引用指向子类对象
* @author Administrator
* */
public abstract class Person {
String sex;
public void eat(){
System.out.println("吃饭");
}
}
- 定义一个Student类
/**
* 继承Person类并重写eat()的方法
* @author Administrator
* */
public class Student extends Person{
/**
* 重写方法
*/
@Override
public void eat() {
System.out.println("学生吃饭");
}
}
- 定义一个Teacher类
/**
* 继承Person类并重写eat()的方法
* @author Administrator
* */
public class Teacher extends Person{
@Override
public void eat() {
System.out.println("老师吃饭");
}
}
- Main方法中运行的结果:
/**
* 多态性测试
* @author LingDu
*
*/
public class Test {
public static void main(String[] args) {
//父类引用指向子类对象
Person student = new Student();
student.eat();
Person teacher = new Teacher();
teacher.eat();
}
}
优点
- 1、可替换性(substitutability)。多态对已存在代码具有可替换性。
- 2、可扩充性(extensibility)。多态对代码具有可扩充性。
- 3、接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 4、灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
- 5、简化性(simplicity)。多态简化对应用软件的代码编写和修改过程。
抽象类与抽象方法
关键字:abstract
1:类前面使用abstract关键字修饰(可能不包含抽像方法)
2:有抽像方法的类也是抽像类(类前面可能没有abstract修饰符)
3:抽像类和普通类的区别:
- 1):抽象方法必须为public或者protected
- 2):抽象类不能用来创建对象;
- 3):如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
- 4):抽像方法:它只有声明,而没有具体的实现
4:抽像头是为了让子类继承而存在的
抽象类只能定义抽象方法
- 创建Father类为抽象类
/**
* 抽象类:
* 父类里必须有一个abstract修饰符
* 方法上也必须有一个修饰符
* 父类不能实现某个抽象方法
* 所有的子类必须都要实现抽象方法
* 不能new一个出来
* @author LingDu
*/
public abstract class Father {
int money ;
//定义一个抽象方法
public abstract void goToUnivercity(String schoolName);
public static void beatChild() {
System.out.println("我是静态方法,我是可以被调用的");
}
}
继承抽象类时必须实现实现所有的方法
//重写父类的方法
public void goToUnivercity(String schoolName) {
//重写父类的抽象方法
}
抽象类不能被实例化出来
抽象类可以调用静态方法
Father.beatChild();
- 创建一个子类:Child类继承Father
/**
* 抽象类
* 抽象类只能定义抽象方法
* 继承抽象类时必须实现实现所有的方法
* 抽象类不能被实例化出来
* 抽象类可以调用静态方法
* @author lingDu
*/
public class Child extends Father{
//重写父类的方法
public void goToUnivercity(String schoolName) {
System.out.println("1:经历2-3年幼儿园");
System.out.println("2:经历6年小学");
System.out.println("2.1:经历1次暗恋");
System.out.println("3:经历6-7年中学");
System.out.println("3.1:经历20-30挨揍");
System.out.println("4:经历"+schoolName+"3-5年大学");
System.out.println("4.1:经历0-2次恋爱");
System.out.println("4.2:经历编程的学习");
}
public static void main(String[] args) {
Child lingdu = new Child();
lingdu.goToUnivercity("哈佛");
Father.beatChild();
}
}
接口
- 关键字:interface
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口定义的一般形式
[访问控制符]interface <接口名> {
类型标识符final 符号常量名n = 常数;
返回值类型 方法名([参数列表]);
…
}
修饰符:可选,用于指定接口的访问权限,可选值为public。
如果省略则使用默认的访问权限。接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符一般情况下,要求首字母大写。
当使用extends关键字时,父接口名为必选参数。方法:接口中的方法只有定义而没有被实现。
在类中实现接口可以使用关键字implements
在类的继承中,只能做单重继承,而实现接口时,一次则可以实现多个接口,每个接口间使用逗号“,”分隔。
实例
/*
接口的特点:
1、接口中的方法都是抽象的,不能实例化对象
2、当一个类实现接口时,如果这个类时抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法
3、一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开。
*/
//定义PCI接口
interface PCI {
void start(); //定义抽象方法start()
void stop(); //定义抽象方法stop()
}
//定义NetWorkCard类实现PCI接口
//网卡类
class NetWorkCard implements PCI {
//实现start()方法
public void start() {
System.out.println("Send......");
}
//实现stop方法
public void stop() {
System.out.println("NetWork Stop......");
}
}
//定义SoundCard类实现PCI接口
//声卡类
class SoundCard implements PCI {
//实现start()方法
public void start() {
System.out.println("Du du......");
}
//实现stop方法
public void stop() {
System.out.println("Sound Stop");
}
}
//定义MainBoard类
//主板类
class MainBoard {
//定义一个usePCICard()方法,接收PCI类型的参数
public void usePCICard(PCI p) {
p.start(); //调用传入对象的start()方法
p.stop(); //调用传入对象的stop()方法
}
}
/**
* 程序
*/
public class Assembler {
public static void main(String[] args) {
MainBoard mb = new MainBoard(); //创建MainBoard类的实例对象
NetWorkCard nc = new NetWorkCard(); //创建NetWorkCard类的实例对象nc
mb.usePCICard(nc); //调用MainBoard对象的usePCICard()方法,将nc作为参数传入
SoundCard sc = new SoundCard(); //创建SoundCard类的实例对象sc
mb.usePCICard(sc); //调用MainBoard对象的usePCICard()方法,将sc作为参数传入
}
}