java07-面向对象2
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
一面向对象的第二个特征继承关键字extends
1.继承的好处
1减少代码的冗余提高代码的复用性。
2便于功能的扩展
3为之后多态性的使用提供了前提
2.继承性的格式
class A extends B{}
A:子类派生类、subclass
B:父类、超类、基类、superclass
3.子类继承父类后有哪些同
体现一旦子类A继承父类B后子类A中就获得了父类B中声明的所有属性和方法。
特别的父类中声明为private的属性或方法子类继承父类以后仍然认为获得了父类的中的结构。只因为封装性的影响使得子类不能直接调用父类的结构而已。
4.java中继承性的说明
1一个类可以被多个子类继承
2java 中类的单继承性一个类只能有一个父类
3子父类是相对的概念
4子类直接继承的父类称为直接父类间接继承的父类称为间接父类
5子类继承父类后就获得了直接父类以及所有间接父类中声明的属性和方法
6如果一个类没有显示的声明一个类的父类的话则此类继承于java.lang.object类
例题基础账户和信用账户
class BaseAccount{
private double balance;
private int id;
private double interestrate;
public BaseAccount(){}
public BaseAccount(double balance, int id, double interestrate) {
super();
this.balance = balance;
this.id = id;
this.interestrate = interestrate;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance=balance;
}
public void overdraw(double balance) {
this.balance = balance;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getInterestrate() {
return interestrate;
}
public void setInterestrate(double interestrate) {
this.interestrate = interestrate;
}
//存钱
public void depsoite(double acct) {
if(acct>0) {
balance+=acct;
System.out.println("存钱成功"+balance);
}
else {
System.out.println("金额错误存钱失败");
}
}
//取钱
public void withdraw(double acct) {
if(acct>balance) {
System.out.println("余额不足");
}else {
balance-=acct;
System.out.println("取钱成功"+acct);
}
}
}
class CreditAccount extends BaseAccount{
private double overdraw;
public CreditAccount() {
}
public CreditAccount(double balance, int id, double interestrate,double overdraw) {
super(balance, id, interestrate);
this.overdraw=overdraw;
}
public double getOverdraw() {
return overdraw;
}
public void setOverdraw(double overdraw) {
this.overdraw = overdraw;
}
public void withdraw(double acct) {
if(acct<getBalance()) {
//方式1
//setBalance(getBalance()-acct);
//方式2
super.withdraw(acct);
}
else if (overdraw>=acct-getBalance()) {
overdraw-=acct-getBalance();
//方式1
//setBalance(0);
//方式2
super.withdraw(getBalance());
}
else {
System.out.println("超过透支余额");
}
}
}
public class TestExtends {
public static void main(String []args) {
CreditAccount ca= new CreditAccount(2000, 1102, 0.45, 5000);
ca.withdraw(1000);
System.out.println("账户余额为"+ca.getBalance());
System.out.println("透支余额为"+ca.getOverdraw());
ca.withdraw(2000);
System.out.println("账户余额为"+ca.getBalance());
System.out.println("透支余额为"+ca.getOverdraw());
ca.withdraw(5000);
System.out.println("账户余额为"+ca.getBalance());
System.out.println("透支余额为"+ca.getOverdraw());
}
}
二eclipse 的debug功能
1.如何调试程序
1打印输出语句System.out.println()
2)eclipse -debug
步骤一 打断点点击代码行左侧点击点的标识
步骤二run as dubug 进入调式模式 右侧显示加载在内存中的变量 工具栏中两个图标step over 逐行 step into 进入 具体的结构
三方法的重写 override/overwrite
1:子类继承父类后可以对父类中同名同参数的方法 进行覆盖操作
2应用重写以后当创建子类对象后通过子类对象调用子父类中同名同参数方法时实际执行的是子类重写父类的方法。
3重写的规定
方法的声明权限修饰符 返回值类型 方法名形参列表{
//方法体
}
约定俗称子类中的叫重写的方法父类中的叫被重写的方法
1子类重写的方法名和形参列表与父类被重写的方法名和形参列表相同
2子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符特殊情况子类不能重写父类声明为private权限的方法
3返回值类型
》父类被重写的方法的返回值类型是void则子类重写的方法的返回值类型只能是void
》父类被重写的方法返回值类型是A类型则子类重写的方法返回值类型可以是A类或A类的子类
》父类被重写的方法的返回值类型是基本数据类型则子类重写的方法的返回值类型必须是相同的基本数据类型
》子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
》子类和父类中的同名同参数的方法要么都声明为非static的考虑重写要么都声明为static(不是重写)
例person类和student类
//person 类
class Person{
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
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("人会吃饭");
}
public void sleep() {
System.out.println("人会睡觉");
}
}
class Student extends Person{
private String major;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age,String major) {
super(name, age);
// TODO Auto-generated constructor stub
this.major=major;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
//方法的重写
public void eat() {
System.out.println("学生要吃有营养的食物");
}
public void study()
{
System.out.println("学生要学习专业课程"+major);
}
}
//测试
public class TestPerson {
public static void main(String[] args) {
Student stu =new Student("tom",20,"it");
//调用子类覆写的方法
stu.eat();
//调用继承父类的方法
stu.sleep();
//调用子类独有的方法
stu.study();
}
}
四关键字super
super关键字的使用
1.super 理解为父类的
2.super 可以用来调用属性、方法、构造器
3.super的使用
》我们可以在子类的方法或构造器中。通过super.属性或super.方法的方式显示的调用父类中声明的属性或方法但是通常情况下我们习惯省略"super."
》特殊情况当子类和父类中定义了同名的属性时我们要想在子类中调用父类中声明的属性则必须显示的使用super.属性表明调用的是父类中声明的属性
》特殊情况下当子类重写了父类的方法后我们想在子类的方法中调用父类中被重写的方法时则必须显式的使用super.方法,表明调用的是父类中被重写的方法
4.super调用构造器
》我们可以在子类的构造器中显示的使用super形参列表的方式调用父类中声明的
指定的构造器
》ssuper形参列表的使用必须声明在子类构造器的首行
》我们在类的构造器中针对this形参列表和super形参列表只能二选一不能同时出现
》在构造器的首行没有显示的声明this形参列表或super形参列表则默认调用的是父类中的空参构造器
例Circle类和Cylinder类
//定义圆类
class Circle{
private double radius;
public Circle() {
super();
}
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea() {
return 3.14*getRadius()*getRadius();
}
}
//定义圆柱类
class Cylinder extends Circle{
private double length;//高
public Cylinder(double length) {
super();
this.length = length;
}
//返回圆柱的体积
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double findVolume() {
return findArea()*getLength();
}
}
public class TestCylinder {
public static void main(String []args) {
Circle c =new Circle(2.0);
System.out.println("圆的面积为"+c.findArea());
Cylinder cy =new Cylinder(5);
cy.setRadius(3);
System.out.println("圆柱的体积为"+cy.findVolume());
}
}
五面向对象第三个特征多态
1.理解多态性可以理解为一个事务的多种形态
2.何为多态性即父类的引用指向子类的对象或子类的对象赋给父类的引用
3.多态的使用虚拟方法的调用
有了对象的多态性以后我们在编译期只能调用父类中声明的方法但在运行期
我们实际执行的是子类重写父类的方法。
总结编译看左边运行看右边。
4.多态性的使用前提@类的继承关系@方法的重写
5.对象的多态性只适用于方法不适应于属性
例题人类和男人
class Human{
private String name;
private int age;
public Human() {
super();
}
public Human(String name, int age) {
super();
this.name = name;
this.age = age;
}
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("人类要吃饭");
}
public void sleep(){
System.out.println("人类要睡觉");
}
}
class Man extends Human{
public void eat() {
System.out.println("男人吃的多力气比较大!");
}
public void earnMoney() {
System.out.println("男人要赚钱养家");
}
}
public class TestDuotai1 {
public static void main(String[] args) {
//多态 父类的引用调用子类的对象
Human p = new Man();
//调用子类的重写的方法
p.eat();
//编译不通过父类无该方法
//p.earnMoney();
}
}
6.向下转型和向上转型
》向上转型多态
》为什么使用向下转型
有了对象的多态性以后内存中实际上是加载了子类特有的属性和方法但是由于变量声明为父类类型导致编译通时只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。如何才能调用子类特有的属性和方法使用向下转型
》如何实现向下转型
使用强制类型转换符
》使用时的注意点
1.使用强转时可以能出现ClassCastException的异常
2.为了避免在向下转型时出现ClassCastExcepton的异常我们在向下转型之前先进行 instanceof的判断一旦返回true就进行向下转型如果返回false不进行向下转型。
7. instanceof 的使用
》instanceof的关键字使用
a instanceof A 判断对象a是否是类A的实例。如果是返回true如果不是返回false
如果 a instanceof A返回true则a instanceof B也返回true其中类B是类A的父类
注a所属的类必须与类A必须是子类和父类的关系否则编译错误
例题人类和男人和女人人类和男人的代码在上个例题
class Women extends Human{
public void eat() {
System.out.println("女人吃的少力气小");
}
public void buy() {
System.out.println("女人喜欢逛街购物");
}
public class TestDuotai1{
public static void main(String[] args) {
//多态 父类的引用调用子类的对象
Human p = new Man();
//调用子类的重写的方法
p.eat();
//编译不通过父类无该方法
//p.earnMoney();
// 报java.lang.ClassCastException 异常
Women w =(Women)p;
}
改进代码
if(p instanceof Women){
//向下转型
Women w= (Women)p;
p.buy();
}
8.谈谈你对多态性的理解面试题
》实现代码的通用性
》Object类中定义的public boolean equalsObject obj{}
》jdbc使用java 程序操作获取数据库连接CRUD数据库MysqlOracle、DB2SqlSever
》抽象类、接口的使用肯定体现 了多态性。抽象类接口不能实现实例化
六java.lang.Object 类
1 Object类的说明
》Object 类是所有java类的根父类
》如果在类的声明中未使用extends关键字指明其父类则默认父类为java.lang.Object 类
》Object类中的功能属性方法就具通用性
属性无
方法equals/toString() / getClass()/ hashCode()/clone()/finalize()
wait()/notify()/ notifyAll()
》Object类只声明了一个空参的构造器
2 equals方法
》是一个方法而非运算符
》只适用于引用数据类型
》Object类中equals()方法的定义
public boolean equalsObject obj){
return (this==obj);}
说明Object 类中定义的equals和==的作用是相同的比较两个对象的地址值是否相同即两个引用是否指向同一个对象实体
》像String 、Date 、File 、包装类等都重写了Object类中的equals方法重写以后比较的不是两个引用的的地址是否相同而是比较两个对象的“实体内容”是否相同
》通常情况下我们自定义的类如果使用equals的话也通常是比较两个对象的“实体内容”是否相同那么我们就需要对object类中的equals进行重写
重写的原则比较两个对象的实体内容是否相同
3 equlas 重写
》手工重写User类属性age和name
public boolean equalsObject obj{
if(this==obj){
return true;
}else if (obj instanceof User){
User u= Userobj;
return this.age==u.age&&this.name.equals(u.name);
}
return false;
}
}
》开发中怎么实现 自动生成
4 回顾 ==运算符的使用
》可以使用在基本数据类型变量和引用数据类型变量中
》如果比较的是基本数据类型变量比较的两个变量保存的数据是否相等不一定类型要相同
》如果比较的是引用数据类型变量比较两个对象的地址值是否相同即两个引用是否指向同一个对象实体符号两边的变量类型一致
5 toString()方法
》当我们输出一个对象的引用时实际上就是调用当前对象的toString
》Object 类中toString)的定义
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
》像String、Date、File、包装类都重写了Object类中的toString方法使得在调用对象的toString时返回对象"实体内容"信息。
》自定义类也可以重写toString方法当调用此方法时返回对象的"实体内容"
》toString重写
public String toString{
return "User[name="+name+",age="+age+"]";
}
七java中的junit单元测试
步骤
1.选中当前工程 -右键选择build path-add libraries-Junit4-下一步
2.创建java类进行单元测试
此时的java 类要求 1此类时public的2此类提供公共的无参构造器
3.此类中声明单元测试方法
此时的单元测试方法方法的权限时public没返回值没形参
4.此单元测试方法上需要声明注解@Test 并在单元测试中导入import org.junit.Test
5. 声明好单元测试方法后就可以在方法体内测试相关代码
6.写完代码后左键双击单元测试方法名右键run as-Junit Test
说明
1.如果 执行结构没有任何异常绿条执行出现异常红条
例 单元测试 动物类和狗类
class Animal{
public void eat() {
System.out.println("动物要吃饭");
}
public void shout() {
System.out.println("动物在喊叫");
}
}
class Dog extends Animal{
public void eat() {
System.out.println("狗在啃骨头");
}
public void shout() {
System.out.println("汪汪汪");
}
public void sleep() {
System.out.println("狗要睡觉");
}
}
class Cat extends Animal{
public void eat() {
System.out.println("猫在吃鱼");
}
public void shout() {
System.out.println("喵喵喵");
}
public void sleep() {
System.out.println("猫要睡觉");
}
}
//单元测试
import org.junit.Test;
public class TestJunitDuoTai {
public TestJunitDuoTai() {}
@Test
public void test1() {
Animal a = new Dog();
a.eat();
a.shout();
}
}
八基本数据类型与包装类
1.为什么要有包装类封装类
》为了使基本数据类型的变量具有类的特征引入包装类。
2.基本的数据类型与对应的包装类
3.基本数据类型 、包装类、String 相互转换
》基本数据类型《》包装类JDK5.0新特性自动装箱与自动拆箱
》基本数类型、包装类--》String调用String类的重载方法valueOfXxx xxx
》String 类--》基本数类型、包装类调用包装类的parseXxxString s
注转换时可能会出现Numbermart String.valueOf("abc")
例基本数据类型与String相互转换
@Test
public void test2() {
//自动装箱
Integer i =10;
Double d =20.0;
System.out.println(i);
System.out.println(d);
//自动拆卸
int s1= i;
double d1=d;
System.out.println(s1);
System.out.println(d1);
//基本数据类型转换为String
int n2=100;
String str1 = String.valueOf(n2);
System.out.println(str1);
//String 转换为基本数据类型
String str2 ="200.12";
double d2=Double.parseDouble(str2);
System.out.println(d2);
}