面向对象的特征主要有以下几个方面:
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
- 封装
- 继承
- 多态
封装
通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
- 隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
我们做一个练习理解一下java的封装:
题目:
创建程序,在其中定义两个类:Account和AccountTest类体会Java的封装性。
Account类要求具有属性:姓名(长度为2位3位或4位)、余额(必须>20)、密码(必须是六位),
如果不满足,则给出提示信息,并给默认值
通过setXxx的方法给Account 的属性赋值。
此处直接上代码:
class Account1 {
public String name;
private int balance;
private int pwd;
public Account1(String name, int balance, int pwd) {
this.name = name;
this.balance = balance;
this.pwd = pwd;
}
@Override//重写 覆盖
public String toString() {
return "Account1{" +
"name='" + name + '\'' +
", balance=" + balance +
", pwd=" + pwd +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
//姓名长度必须是2位——4位
if(name.length()>2&&name.length()<=4){
this.name = name;
}else{
System.out.println("名字输入无效");
this.name="无名";
}
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
if(balance >20 ){
this.balance = balance;
}else{
System.out.println("您的余额不能小于20");
}
}
public int getPwd() {
return pwd;
}
public void setPwd(int pwd) {
/*if (pwd.length ==6) {
this.pwd = pwd;
}else{
System.out.println("密码需要6位,默认000000");
}*/
this.pwd = pwd;
}
}
class Account1Test {
//Account1 account1 = new Account1();
}
class AccountTest {
public static void main(String[] args) {
MyBankAccount myBankAccount=new MyBankAccount("1000","0000000","324324");
myBankAccount.query("0000000");
myBankAccount.deposit("0000000",373463874);
myBankAccount.query("0000000");
myBankAccount.withraw("0000000",65843);
myBankAccount.query("0000000");
}
}
继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
关于继承如下 3 点请记住:
子类拥有父类非 private 的属性和方法。
子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
我们做一个练习理解一下java的继承:
编写Computer类,包含CPU、内存、硬盘等属性,
getDetails方法用于返回Computer的详细信息
编写PC子类,继承Computer类,添加特有属性【品牌brand】
编写NotePad子类,继承Computer类,添加特有属性【演示color】
编写Test类,在main方法中创建PC和NotePad对象,
分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用方法并打印输出信息
/* @author:caiwan
* @desc:extend
*/
public class Computer {
public static void main(String[] args) {
// 测试
PC pc = new PC("intel 7.0", "IBM笔记本", 16, 500);
System.out.println(pc.showInfo());
Computer1 computer1 = new Computer1("intel 8.0", 24, 600);
System.out.println(computer1.getDetail());
}
}
class Computer1 {
private String CPU;
private int mem;
private int disk;
public Computer1(String cPU, int mem, int disk) {
super();
CPU = cPU;
this.mem = mem;
this.disk = disk;
}
public String getCPU() {
return CPU;
}
public void setCPU(String cPU) {
CPU = cPU;
}
public int getMem() {
return mem;
}
public void setMem(int mem) {
this.mem = mem;
}
public int getDisk() {
return disk;
}
public void setDisk(int disk) {
this.disk = disk;
}
public String getDetail() {
return "cpu=" + CPU + " mem =" + mem + " disk=" + disk;
}
}
class PC extends Computer1 {
private String brand; // 品牌.
public PC(String cpu, String brand, int mem, int disk) {
super(cpu,mem,disk); //使用父类构造器,完成父类属性的初始化
this.brand = brand;
}
//看看如何得到PC的信息
public String showInfo() {
//方法1. 使用父类提供的public 方法获取私有属性.
//在实际开发中,看到子类去调用父类方法,完成某个任务.
return getDetail() + " brand=" + brand;
}
}
多态
多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。
多态性分为编译时的多态性和运行时的多态性。
如果将对象的方法视为对象向界提供的服务,那么运行时的多态性可以解释为:
当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,
但一切对 A 系统来说都是透明的。
abstract class Animal{
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void kanJia(){
System.out.println("狗看家");
}
}
class duotaiDemo{
public static void main(String[] args){
funcation(new Dog());
funcation(new Cat());
public static void funcation(Animal a){
a.eat();
if(a instanceof Cat){
Cat c=(Cat)a;
c.catchMouse();
}else if(a instanceof Dog){
Dog d=(Dog)a;
d.kanJia();
}
}
}
}
class Fu
{
public void method1(){
System.out.println("Fu...Method1");
}
public void method2(){
System.out.println("Fu...Method2");
}
}
class Zi extends Fu
{
public void method1(){
System.out.println("Zi...Method1");
}
public void method3(){
System.out.println("Zi...Method3");
}
}
class duoTaiDemo3
{
public static void main(String[] args){
Fu f=new Zi();
f.method1();
f.method2();
f.method3();
}
}
// 报错原因Fu类中没有method3()这个方法。
在Java中有两种形式可以实现多态:
- 继承(多个子类对同一方法的重写)
- 接口(实现接口并覆盖接口中同一方法)。
方法重载(overload)实现的是编译时的多态性(也称为前绑定)
- 子类继承父类并重写父类中已有的或抽象的方法
方法重写(override)实现的是运行时的多态性(也称为后绑定)
- 子类继承父类并重写父类中已有的或抽象的方法
成员函数在多态调用时,编译看左,运行看右;
成员变量:无论编译还是运行,都看左(引用型变量所属的类)
静态成员函数的特点:无论编译还是运行,都看左边。