---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
技术博客1:面向对象的四大特征实例
1抽象
当多个类中出现了相同功能,但功能主题不同,这时可以向上抽取,只抽取功能定义,而不抽取功能主体。
特点:
抽象方法一定定义在抽象类中
抽象方法和抽象类都必须被abstract关键字修饰
抽象类不可以用new创建对象,因为调用抽象方法没定义
抽象类中的方法要被调用,必须由子类复写所有的抽象方法后,建立子类对象调用
如果子类只覆盖了部分抽象方法,那么该子类还是抽象类
抽象类中可以不定义抽象方法,看上去没意义,这样做仅仅是不让类建立对象。
求自定义几何图形的面积和周长的例子
代码:
//定义抽象类,每个图形都有求面积,和求周长的方法
abstract class Geometry
{
abstract double getArea();
abstract double getPerimeter();
}
//定义一个等边三角形类,继承图形类
class Equilateraltriangle extends Geometry
{
double width;
double height;
Equilateraltriangle(double width,double height)
{
this.width=width;
this.height=height;
}
//实现父类的抽象方法求等边三角形的面积
double getArea()
{
return (this.width+this.height)/2;
}
//实现父类的抽象方法求等边三角形的周长
double getPerimeter()
{
return width*3;
}
}
//定义一个长方形类,继承图形类
class Rectangles extends Geometry
{
double width;
double height;
Rectangles(double width,double height)
{
this.width=width;
this.height=height;
}
//实现父类的抽象方法求长方形的面积
double getArea()
{
return this.width*this.height;
}
//实现父类的抽象方法求长方形的周长
double getPerimeter()
{
return 2*(this.width+this.height);
}
}
//定义一个圆类,继承图形类
class Circle extends Geometry
{
double r;
Circle(double r)
{
this.r=r;
}
//实现父类的抽象方法,求圆的面积
double getArea()
{
return Math.PI*r*r;
}
//实现父类的抽象方法,求圆的周长
double getPerimeter()
{
return 2*Math.PI*r;
}
}
class AbstractClassExample
{
public static void main(String[] args)
{
sop("1.获取等边三角形的面积和周长");
//创建等边三角形的实例
Equilateraltriangle triangle=new Equilateraltriangle(10,5);
sop("等边三角形的面积:"+triangle.getArea());
sop("等边三角形的周长:"+triangle.getPerimeter());
sop("2.获取长方形的面积和周长");
//创建长方形的实例
Rectangles rectangle=new Rectangles(12,8);
sop("长方形的面积:"+rectangle.getArea());
sop("长方形的周长:"+rectangle.getPerimeter());
sop("3.获取圆的面积和周长");
//创建圆的实例
Circle circle=new Circle(5);
sop("圆的面积:"+circle.getArea());
sop("圆的周长:"+circle.getPerimeter());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
运行结果:
2 封装
封装:是指隐藏对象的属性和实现细节,反对对外提供公共访问方式
封装原则:
将不需要对外提供的内容都隐藏
把属性都隐藏,提供公共方法对其访问
自定义复数类的例子
代码:
class Plural
{
//定义实部和虚部
private double realPart;
private double imaginaryPart;
//如果没传参数,默认为0;
public Plural()
{
this.realPart=0.0;
this.imaginaryPart=0.0;
}
//带参数的构造函数
public Plural(double realPart,double imaginaryPart)
{
this.realPart=realPart;
this.imaginaryPart=imaginaryPart;
}
//设置实部的值
public void setRealPart(double realPart)
{
this.realPart=realPart;
}
//获得实部的值
public double getRealPart()
{
return this.realPart;
}
//设置虚部的值
public void setImaginaryPart(double imaginaryPart)
{
this.imaginaryPart=imaginaryPart;
}
//获得虚部的值
public double getImaginaryPart()
{
return this.imaginaryPart;
}
//复数的加法,实部相加为实部,虚部相加为虚部
public Plural add(Plural plural)
{
if(plural==null)
{
System.out.println("对象不能为空");
return new Plural();
}
return new Plural(this.realPart+plural.realPart,this.imaginaryPart+plural.imaginaryPart);
}
//复数的减法,实部相减为实部,虚部相减为虚部
public Plural substruction(Plural plural)
{
if(plural==null)
{
System.out.println("对象不能为空");
return new Plural();
}
return new Plural(this.realPart-plural.realPart,this.imaginaryPart-plural.imaginaryPart);
}
//复数的乘法,c.实部=a.实部*b.实部-a.虚部*b.虚部;c.虚部=a.实部*b.虚部+a.虚部*b.实部
public Plural multiplication(Plural plural)
{
if(plural==null)
{
System.out.println("对象不能为空");
return new Plural();
}
return new Plural(this.realPart*plural.realPart-this.imaginaryPart*plural.imaginaryPart,this.realPart*this.imaginaryPart+this.imaginaryPart*plural.realPart);
}
//复数的除法,c.实部=(a.实部*b.实部+a.虚部*b.虚部)/(b.实部*b.实部+b.虚部*b.虚部);c.虚部=(a.实部*b.虚部-a.虚部*b.实部)/(b.实部*b.实部+b.虚部*b.虚部)
public Plural division(Plural plural)
{
if(plural==null)
{
System.out.println("对象不能为空");
return new Plural();
}
if((plural.getRealPart()==0)&&(plural.getImaginaryPart()==0))
{
System.out.println("除数不能为0");
return new Plural();
}
double temp_real=(this.realPart*plural.realPart+this.imaginaryPart*plural.imaginaryPart)/(plural.realPart*plural.realPart+plural.imaginaryPart*plural.imaginaryPart);
double temp_imaginary=(this.realPart*plural.imaginaryPart-this.imaginaryPart*plural.realPart)/(plural.realPart*plural.realPart+plural.imaginaryPart*plural.imaginaryPart);
return new Plural(temp_real,temp_imaginary);
}
//复写用字符串的形式表示
public String toString()
{
return this.realPart+"+"+this.imaginaryPart+"i";
}
}
class PluralTest
{
public static void main(String[] args)
{
Plural x=new Plural(2,4);
Plural y=new Plural(1,2);
sop("x的值为:"+x.toString());
sop("y的值为:"+y.toString());
sop("x+y的值为:"+x.add(y).toString());
sop("x-y的值为:"+x.substruction(y).toString());
sop("x*y的值为:"+x.multiplication(y).toString());
sop("x/y的值为:"+x.division(y).toString());
}
//由于多次使用输出,所以提取出一个函数
public static void sop(Object obj)
{
System.out.println(obj);
}
}
运行结果:
3 继承
继承:
将多个有关系类的共性内容提取出来单独进行描述。
继承的好处:
提高了代码的复用性
让类与类之间产生了关系,有了这个关系,才有了多态的特征;
注意:
千万不要为了获取其他类的功能,简化代码而继承;必须是类与类之间有所属关系才可以继承,类抽象出来父类;
Java只支持单继承,但是可以多实现;
如果子父类中出现非私有的同名成员变量时,子类要访问本类的变量,用this关键字;子类要访问父类中的同名变量,用super关键字;
银行自动存取一体机
代码:
import java.io.*;
//普通用户的功能实现
class Common_Card
{
String name;
int ID;
int password;
double money;
Common_Card(String name,int ID,int password,double money)
{
this.name=name;
this.ID=ID;
this.password=password;
this.money=money;
}
//取款操作
boolean checkMoney(int m)
{
System.out.println("正在操作,请稍后、、、");
if(m<0)
{
if(saveMoney(-m))
{
return true;
}
else
{
return false;
}
}
else
{
if(m>this.money)
{
System.out.println("该账户不可透支,本次操作中断。。。");
return false;
}
else
{
this.money-=m;
System.out.println("操作成功。。。");
return true;
}
}
}
//存款操作
boolean saveMoney(int m)
{
if(m<0)
{
if(checkMoney(-m))
{
return true;
}
else
{
return false;
}
}
else
{
this.money+=m;
System.out.println("操作成功。。。");
return true;
}
}
//显示余额
void searchMoney()
{
System.out.println(this.name+"[ID:"+this.ID+"] 余额:"+this.money+"元");
}
//检验密码
boolean checkPassword()
{
int i;
for(i=0;i<3;i++)
{
if(i>0)
System.out.println("密码错误,重新输入。。。");
int pw=EnterDate.scanInt();
if(pw==this.password)
return true;
}
if(i==3)
{
System.out.println("密码输入出错三次,操作中断...");
}
return false;
}
//正在执行所选择的项目
void operating(Common_Card st[])
{
while(true)
{
this.printReceipt();
int cmd=EnterDate.scanInt();
switch(cmd)
{
case 1:
{
System.out.println("请输入存款数...");
int m=EnterDate.scanInt();
saveMoney(m);
break;
}
case 2:
{
System.out.println("请输入取款数...");
int m=EnterDate.scanInt();
checkMoney(m);
break;
}
case 3:
{
searchMoney();
break;
}
case 0:
{
Machine.end=0;
return;
}
}
}
}
//功能提示界面
void printReceipt()
{
System.out.println("自动提款机普通用户操作界面");
System.out.println(" ------------ ");
System.out.println(" [存款-----1] ");
System.out.println(" [取款-----2] ");
System.out.println(" [余额-----3] ");
System.out.println(" [退卡-----0] ");
System.out.println(" ------------ ");
}
}
//Vip_Card类的Vip用户功能实现
class Vip_Card extends Common_Card
{
//构造函数
Vip_Card(String name,int ID,int password,double money)
{
super(name,ID,password,money);
}
//不仅具有取钱的功能,还可以透支,覆写checkMoney方法
boolean checkMoney(int m)
{
if(m<0)
{
if(saveMoney(-m))
{
return true;
}
else
{
return false;
}
}
else
{
if(m-5000>this.money)
{
System.out.println("该用户透支不可超过5000元。。。本次操作中断!");
return false;
}
else
{
this.money-=m;
System.out.println("操作成功。。。");
return true;
}
}
}
//比普通用户多了转账功能,
void transferMoney(Common_Card st[])//多态
{
System.out.println("请输入目标账户ID:");
int id=EnterDate.scanInt();
int i;
for (i=0; i<st.length ;i++)
{
if(st[i].ID==id)
{
System.out.println("请输入转账金额:");
int m=EnterDate.scanInt();
if(m<0)
{
System.out.println("请输入目标账户的密码:");
if(st[i].checkPassword()==false)
{
return;
}
}
else
{
if(this.checkMoney(m))
{
st[i].saveMoney(m);
System.out.println("转账成功。。。");
}
else
{
System.out.println("转账失败。。。");
}
break;
}
}
}
if(i==st.length)
System.out.println("用户不存在!");
}
//正在操作 覆写operating方法
void operating(Common_Card st[])
{
while(true)
{
this.printReceipt();
int cmd=EnterDate.scanInt();
switch(cmd)
{
case 1:
{
System.out.println("请输入存款数。。。");
int m=EnterDate.scanInt();
saveMoney(m);
break;
}
case 2:
{
System.out.println("请输入取款数。。。");
int m=EnterDate.scanInt();
checkMoney(m);
break;
}
case 3:
{
searchMoney();
break;
}
case 4:
{
transferMoney(st);
break;
}
case 0:
{
Machine.end=0;
return;
}
}
}
}
//Vip用户功能提示操作界面
void printReceipt()
{
System.out.println("自动提款机VIP用户操作界面");
System.out.println(" ------------ ");
System.out.println(" [存款-----1] ");
System.out.println(" [取款-----2] ");
System.out.println(" [余额-----3] ");
System.out.println(" [转账-----4] ");
System.out.println(" [退卡-----0] ");
System.out.println(" ------------ ");
}
}
//该类主要的功能是从控制台录入数据,及数据的预处理。
class EnterDate
{
//从控制台接收数据
static String scan()
{
String str="";
try
{
BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
str=buf.readLine();
}
catch (Exception e)
{
e.printStackTrace();
}
return str;
}
//将从键盘上录入的数据转换成int型
static int scanInt()
{
int temp=0;
try
{
temp=Integer.parseInt(scan());
}
catch (Exception e)
{
System.out.println("输入不合法,请输入整数。。。");
}
return temp;
}
}
class Machine
{
static int end=1;
public static void main(String[] args)
{
//创建一个有4个用户的数组
Common_Card st[]=new Common_Card[4];
//创建2个普通用户
st[0]=new Common_Card("未知",999,999,0);
st[1]=new Common_Card("聂庆亮",200981501,10010,100000);
//创建2个Vip用户
st[2]=new Vip_Card("张三",1111,11,9999);
st[3]=new Vip_Card("李四",2222,22,99);
while(true)
{
if(end==0)
{
System.out.println("谢谢您的使用,再见!");
return;
}
System.out.println("请输入账户ID:[0:退出]");
int id=EnterDate.scanInt();
if(id==0)
return;
int i;
for (i=0; i<st.length ;i++ )
{
if(st[i].ID==id)
{
System.out.println("请输入账户密码。。。");
if(st[i].checkPassword())
{
st[i].operating(st);
break;
}
}
}
if(i==st.length)
{
System.out.println("该用户不存在!");
}
}
}
}
普通用户运行结果:
Vip用户运行结果:
4 多态
多态的体现:
父类的引用指向了自己子类对象;
父类的引用也可以接收自己的子类对象;
注意:
千万不要将父类对象转成子类类型;
父类引用指向了自己子类对象时,该应用可以被提升,也可以被强制转换;
多态自始至终都是子类做着变化;
多态的例子
代码:
import java.util.Date;
//人类
class Person
{
String name;
Date date=new Date();
int hour=date.getHours();//获得时间
//吃饭时间
public void dinnerTime(Person person)
{
if(this.hour<=8&&this.hour>7)
{
this.breakFast(person);
}
else if(this.hour<=13&&this.hour>11)
{
this.lunch(person);
}
else if(this.hour<=20&&this.hour>=17)
{
this.dinner(person);
}
}
//吃早餐
public void breakFast(Person person)
{
System.out.println(this.name+"到吃早餐的时间了。。。");
}
//吃午餐
public void lunch(Person person)
{
System.out.println(this.name+"到吃午餐的时间了。。。");
}
//吃晚餐
public void dinner(Person person)
{
System.out.println(this.name+"到吃晚餐的时间了。。。");
}
}
//中国人继承Person类
class Chinese extends Person
{
//覆写父类的方法
public void dinnerTime(Chinese person)
{
Chinese cns=new Chinese();
if(this.hour<=8&&this.hour>7)
{
this.breakFast(cns);
}
else if(this.hour<=13&&this.hour>11)
{
this.lunch(cns);
}
else if(this.hour<=20&&this.hour>=17)
{
this.dinner(cns);
}
}
//吃早餐
public void breakFast(Chinese person)
{
System.out.println("中国人早餐吃:包子,油条,粥,豆浆。。。");
}
//吃午餐
public void lunch(Chinese person)
{
System.out.println("中国人中午吃米饭,馒头,蔬菜和肉。。。");
}
//吃晚餐
public void dinner(Chinese person)
{
System.out.println("中国人晚上吃蔬菜和水果、、、");
}
//子类特有的方法
public void personal()
{
System.out.println("我是中国人。");
}
}
//Foreigners 继承了Person类
class Foreigners extends Person
{
//覆写父类的方法
public void dinnerTime(Foreigners person)
{
Foreigners frs=new Foreigners();
if(this.hour<=8&&this.hour>7)
{
this.breakFast(frs);
}
else if(this.hour<=13&&this.hour>11)
{
this.lunch(frs);
}
else if(this.hour<=20&&this.hour>=17)
{
this.dinner(frs);
}
}
//吃早餐
public void breakFast(Foreigners person)
{
System.out.println("外国人早餐吃面包,牛奶。。。");
}
//吃午餐
public void lunch(Foreigners person)
{
System.out.println("外国人中午吃汉堡,马铃薯。。。");
}
//吃晚餐
public void dinner(Foreigners person)
{
System.out.println("外国人晚上吃甜点和水果,面包、、、");
}
//子类特有的方法
public void personal()
{
System.out.println("I am a British!");
}
}
class MyDay
{
public static void main(String[] args)
{
//实例化对象
Person p=new Chinese();
p.name="zhangsan";
p.dinnerTime(p);
//创建子类对象
Chinese c=new Chinese();
c.personal();
c.dinnerTime(c);
System.out.println();
Person p1=new Foreigners();
p1.name="tom";
p1.dinnerTime(p1);
Foreigners f=new Foreigners();
f.personal();
f.dinnerTime(f);
}
}