3.组合,继承!

 

一,继承

1,向上转型

子类对象可以当做父类对象使用,因为父类有的功能子类都有;

父类对象不能当子类使用,因为子类有的功能父类不一定有;

父类变量引用子类对象时,不能调用子类特有方法,因为编译时会报错;

2,强制类型转换

子类当父类来使用时,如果想调用子类特有方法,需要强制类型转换为子类,才能      调用;

如果父类变量记住的是父类对象,这时不能强转;

强转的代码在编译时不会报错,通常会用instanceof判断之后再进行强转;

例如: class Person {}  定义一个人类

class Student extends Person {} 定义一个学生类继承人类

class Demo {

Person p = new Student();  是向上转型,子类当父类使用

If(p instanceof Student )             使用instanceof判断p是否属于学生类

return Student s = (Student ) p;           如果是,则强转

}

3,重写方法

子类可以重写父类方法,一旦重写,调用时就会找子类重写后的方法;

如果需要调用父类被覆盖的方法,可以使用super关键字;

重写方法时,返回值类型和参数列表必须全部相同,访问权限不能更低;

访问权限排列:

public > protected > default > private

4@Override

注解,加载方法前,用来检查当前方法是否覆盖父类的一个方法

如果成功覆盖,编译会通过;如果没有覆盖,编译会报错;

class Demo {

       public static voidmain(String[] args) {

              //子类对象当父类对象使用

              Person p = new Student();

              //父类变量使用子类特有方法,会报错

              //p.study();

              //使用instanceof判读变量类型,如果是,父类变量强制转换成子类变量;

              if( p instanceof Person) {

                     Student s =(Student)p;

                     s.study();

              }

              else

                     System.out.println("不是Person类型,不能转换");

       }

}

class Person {

       String name;

       int age;

      

       public void eat() {

              System.out.println("吃饭"); 

       }

 

}

class Student extends Person {

       //检测子类的eat方法是否覆盖了父类的eat方法

       @Override

       //父类中的eat方法重写

       public void eat() {

              System.out.println("Student吃饭");    

       }

       public void study() {

              System.out.println("学习"); 

       }    

}

二,组合设计模式

1,什么是组合设计模式

当定义一个类需要使用另一个类的方法时,就可以使用组合设计模式;

2,组合设计模式的写法

定义成员变量,用来引用被组合的对象;

构造函数接收一个被组合的对象,用成员变量引用;

在需要使用被组合类的方法时,通过成员变量调用被组合对象的方法;

3,组合和继承的区别:

在两个类没有逻辑上的父子关系,不适合使用继承,就使用组合设计模式;

Java只支持单继承,组合不占用继承的位子;

如果使用继承,子类可以当做父类使用,支持了多态;

4,组合,继承分别在什么情况下使用

在定义类需要使用另一个类的方法时,这两种方式都可以实现;

如果定义的一个类要当做另一个类使用,就必须使用继承;

如果不需要使用父类,建议使用组合;

class CompositeDemo {

      

       public static voidmain(String[] args) {

              Card c = new Card();

              c.save(6000);

             

              Person p = new Person(c);

              p.shopping();

              p.eat();

             

              System.out.println("卡里还剩: " + c.getBalance());

       }    

      

}

 

class Person {

       private Card card;                 // 1.定义成员变量,用来引用被组合的对象

      

       public Person(Card card){    // 2.构造函数接收一个被组合的对象,用成员变量引用

              this.card = card;

       }

      

       public void shopping() {

              card.spend(5000);          // 3.通过成员变量调用被组合对象的方法

              System.out.println("买了一台iPhone5");

       }    

      

       public void eat() {

              card.spend(500);

              System.out.println("吃了一顿全聚德");     

       }

}

 

class Card {

       private int balance;                      //卡的余额

      

       public void spend(intamount) {           //刷卡消费, amount为金额

              System.out.println("刷卡消费,花了" +amount + "");

              balance -= amount;

       }

      

       public void save(intamount) {

              balance += amount;

       }

      

       public int getBalance(){

              return balance;      

       }

}

三,垃圾回收

1,对象的销毁

对象的生命周期从new建立对象开始,在没有任何数据指向的时候生命周期结束;

当一个对象生命周期结束的时候,它就成为了一个垃圾对象,垃圾对象并不是立即就回收;

 Java程序中的垃圾对象是在占用空间过大的时候,才会由垃圾回收器回收;

2finalize

finalizeObject的一个类,所有的类都会继承到这个方法;

在对象销毁之前就会执行它;

3,手动清理垃圾

System.gc()可以通过垃圾回收器回收程序中的垃圾对象;

class GcDemo {

       public static voidmain(String[] args) throws Exception {

              //循环,建立1000个无指向的newPerson对象

              for(int x=0; x<1000; x++)

                     new Person();

              //通知垃圾回收器清理垃圾,异步方法,销毁需要一段时间

              System.gc();

              //当前程序休眠1000毫秒;

              Thread.sleep(1000);

              System.out.println(Person.x);

       }

}

class Person {

       //用来统计person类中对象的数量;

       public static int x;

       public Person() {

              //每创建对象时自增;

              x++;      

       }

      

       @Override

       //重写object类的对象,对象被销毁之前执行;

       public void finalize() {

              //每销毁对象时自减;

              x--; 

       }

}

四,对象转字符串

1Object类的toString()

Object类的toString()会被所有的类继承,这个方法可以将对象转为字符串

默认返回“类名@地址”;

2,自定义toString()

如果我们定义一个类,希望别人使用的时候不返回地址,可以重写toString()方法,在toString()中返回希望我们返回的值,例如返回对象的属性值

3System.out.println()

这个方法打印一个对象的时候,默认会调用对象的toString(),打印其返回值;

class ToStringDemo {

       public static voidmain(String[] args) {

              Person p = new Person();

              p.name ="传智";

              p.age =12;

             

              System.out.println(p);   

       }

      

}

class Person {

       String name ;

       int age;

       //检测子类方法是否覆盖了当前父类的方法

       @Override

       //重写object类中的toString()方法,

       public String toString(){

              return name +" , "+age;

       }

}    

五,对象的比较

1,使用==进行比较对象

java中使用==比较2个对象时是比较2个对象的地址是否相同,也就是判断2个对象是否是同一个类;

通常我们希望比较2个对象的内容(成员变量)是否完全相同,就无法使用==进行比较了

 

2equals比较

Object类中提供了equals方法用来比较对象,但其默认的实现是比较地址,如果我们不想比较地址,可以在类中重写该方法;

equals中比较2个类的属性是否完全相同;

 

class Equals {

       public static voidmain(String[] args) {

             

              Person p1 = new Person("李斯",21);

             

              Person p2 = new Person("李斯",21);

              //比较地址值是否相同;

              System.out.println(p1 == p2);

              //使用自定义的equals比较属性是否完全相同

              System.out.println(p1.equals(p2));

       }

}

 

class Person {

       //成员变量通常都私有化

       private String name;

       private int age;

      

       //创建person有参构造函数

       public Person(Stringname, int age) {

              this.name = name;

              this.age = age;

       }

       //检测当前类是否重写当前父类的方法;

       @Override

       //核心代码,增加判断条件,提高代码的健壮性;

       public booleanequals(Object obj) {

              //地址相同,代表传入的是同一个对象,不用比较,直接返回true

              if(this == obj)

                     return true;

             

              //如果传入的对象为null,不用比较,直接返回false

              if(obj == null)

                     return false;

             

              //如果obj不是person类型,不用比较,直接返回false

              if(!(obj instanceof Person))

                     return false;

             

              //为了访问nameage,将object类的实参强转回person类型

              Person other = (Person)obj;

             

              //如果名字一个为null,另一个不为null,返回false

              //如果2个那么都为null,返回true

              if(this.name == null) {

                     if(other.name !=null)

                            return false;   

              }

             

              //如果name不同,返回false,

              //这里的equals调用的是object类中stringequals;因为name的类型是String

              if(!this.name.equals(other.name))

                     return false;

             

              /*name不同,返回false

              if(this.name != other.name)

                     return false;*/

                    

              //age不同,返回false

              if(this.age != other.age)

                     return false;

              //上面没有返回,就代表成员变量相同,返回true

              return true;

       }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值