黑马程序员——java学习4(84-106)——面向对象——继承、多态

1、继承extends

复用性提高,让类与类之间产生了关系,也引起了多态。

查阅父类描述,创建子类对象

子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;

子类要访问父类总的同名变量,用super;

1.1重写(覆盖)

当子类出现和父类一模一样的函数时,子类对象调用该函数,会运行子类函数的内容。

如同父类函数被覆盖一样。

注意:

(1)、子类覆盖父类,必须保证子类权限>= 父类权限

(2)、静态只能覆盖静态

与重载比,包括返回值类型都一模一样

1.2构造函数重写

子类所有的构造函数的第一行,都有隐式的super();放在第一行

父类若无,子类的构造函数必须指定调用某个父类的构造函数

要么有this,要么super只能一个

子类至少有一个构造函数会访问父类的构造函数

2、最终final

修饰符,可类、变量、函数,

被final修饰的类不可被继承,

方法不可被覆写,

变量变常量只能赋值一次成员变量局部变量皆可(记得大写)

内部类定义在类的局部位置上时,只能访问该局部被final修饰的局部变量

3、抽象abstract

修饰符,类、方法

多个类中出现相同方法,但是方法主体不同,则向上抽取,只抽定义,但其还是可以有非抽象方法,甚至可以没有抽象方法,仅为了不让类建对象。

抽象方法必须在抽象类中,类不可被new

抽象类中的抽象方法要被使用,必须由子类覆写起所有的抽象方法后,建立子类对象调用

  如果子类只覆写了部分抽象方法,那些该子类还是一个抽象类

好处:强迫子类做一些功能

即知道子类会做,但不清楚怎么做,便抽象。

 1 package learn;
 2 abstract class Employee{
 3     private String name;
 4     private String num;
 5     private double pay;
 6     Employee(String name,String num,double pay){
 7         this.name=name;
 8         this.num=num;
 9         this.pay=pay;
10     }
11     public abstract void work();
12     
13 }
14 
15 class Pro extends Employee{
16     Pro(String name,String num,double pay){
17         super(name,num,pay);            
18     }
19     public void work()
20     {
21         System.out.print("Pro work");
22     }
23 }
24 class Mana extends Employee{
25     Mana(String name,String num,double pay){
26         super(name,num,pay);
27     }
28     public void work()
29     {
30         System.out.print("Mana Work");
31     }
32     
33 }
34 public class AbstractDemo {
35     public static void main(String[] args)
36     {
37         Mana a=new Mana("lisi","ceshi11",40);
38         a.work();
39         Pro b=new Pro("zhangsan","kaifa1",30);
40         b.work();
41     }
42 }

4、模板方法

功能不确定的部分暴露出去由该类的子类去完成。

 1 package learn;
 2 
 3 abstract class GetTime{
 4     public final void getTime(){
 5         long start=System.currentTimeMillis();
 6         runcode();
 7         long end=System.currentTimeMillis();
 8         System.out.println("毫秒"+(end-start));
 9     }
10     public abstract void runcode();
11 }
12 class SubTime extends GetTime{
13     public void runcode(){
14         for(int i=0;i<1000;i++)
15         {
16             
17         }
18     }
19 }
20 public class AbstractDemo2 {
21     public static void main(String[] args)
22     {
23         SubTime s=new SubTime();
24         s.getTime();
25     }
26 }

5、接口interface

特殊的抽象类,当抽象类中的方法都是抽象的。不可创建对象,子类也需全部覆盖其抽象方法

class用于定义类

interface定义接口

接口中的成员都是public

已默认为:

常量: public static final

方法: public abstract

 1 package learn;
 2 interface Inter{
 3     public static final int num=3;
 4     public abstract void show();
 5 }
 6  class Test1 implements Inter{
 7     public void show(){    
 8     }
 9 }
10 public class InterfaceDemo {
11     public static void main(String[] args)
12     {
13         Test1 x=new Test1();
14         System.out.println(x.num);
15         System.out.println(Test1.num);
16         System.out.println(Inter.num);
17     }
18 }


接口与类之间是实现implements,接口与接口之间是继承,接口间存在多继承, 但还是无法同名不同返回值

 1 interface A{
 2      
 3  }
 4 interface B{
 5      
 6  }
 7  
 8 interface C extends A,B{
 9      
10 }
11 class AA{}
12 class BB extends AA implements A,B{}//多实现方式

接口就是体系以外的功能扩展,基本功能定义在类中

 1 package learn;
 2 abstract class Student{
 3     abstract void study();
 4     void sleep()
 5     {
 6         System.out.println("sleep");
 7     }
 8 }
 9 interface Smoking{
10     void smoke();
11 }
12 class ZhangSan2 extends Student implements Smoking{
13     void study(){}
14     public void smoke(){}
15 }
16 class LiSi extends Student{
17     void study() {    
18     }
19     
20 }
21 public class InterfaceTestDemo {
22 
23 }

6、多态

Animal a=new Cat();//类型提升,向上转型

Cat c=(Cat)a;//向下转型

多态自始至终都是子类对象在做变化

体现:

父类的引用指向了自己的子类对象

父类的引用也可以接受自己的子类对象

前提:必须类与类之间有关系,存在覆盖

好处:提高程序的扩展性

弊端:只能使用父类的引用访问父类中的成员

示例:

 1 package learn;
 2 
 3 abstract class Students{
 4     public abstract void study();
 5     public void sleep(){
 6         System.out.println("躺着睡");
 7     }
 8 }
 9 
10 class BaseStudent extends Students{
11     public void study(){
12         System.out.println("base study");
13     }
14     public void sleep(){
15         System.out.println("坐着睡");
16     }
17 }
18 
19 class AdvStudent extends Students{
20     public void study(){
21         System.out.println("adv study");
22     }
23 }
24 
25 class DoStudent{
26     public void doSome(Students stu)
27     {
28         stu.study();
29         stu.sleep();
30     }
31 }
32 public class DuoTaiDemo3 {
33     public static void main(String[] args) {
34         DoStudent ds=new DoStudent();
35         ds.doSome(new BaseStudent());
36         ds.doSome(new AdvStudent());
37     }
38 }

6.2、多态中成员函数和成员变量

常用:

成员函数,编译时看左边,运行时看右边。

面试:

静态成员函数看左

成员变量,无论编译和运行,都看左边

 1 package learn;
 2 
 3 class Fu{
 4     int num=5;
 5     void method1(){
 6         System.out.println("fu method1");
 7     }
 8     void method2(){
 9         System.out.println("fu method2");
10     }
11     static void method4(){
12         System.out.println("fu method4");
13     }
14 }
15 class Zi extends Fu{
16     int num=8;
17     void method1(){
18         System.out.println("zi method1");
19     }
20     void method3(){
21         System.out.println("zi method3");
22     }
23     static void method4(){
24         System.out.println("zi method4");
25     }
26 }
27 public class DuoTaiDemo4 {
28     public static void main(String[] args)
29     {
30         
31 //        //输出zi1,fu2,zi3
32 //        Zi zi=new Zi();
33 //        zi.method1();
34 //        zi.method2();
35 //        zi.method3();
36         
37 //        //编译失败,3找不到,省去最后一次,结果zi1,fu2,
38 //        Fu f=new Zi();
39 //        f.method1();
40 //        f.method2();
41 //        f.method3();
42         
43 //        //成员变量参考左边
44 //        Fu f=new Zi();
45 //        System.out.println(f.num);
46 //        Zi z=new Zi();
47 //        System.out.println(z.num);
48 
49 //        //静态成员变量看左
50 //        Fu f=new Zi();    
51 //        f.method4();
52 //        Zi z=new Zi();
53 //        z.method4();
54     }
55 }

接口示例-主板与声卡网卡

 1 package learn;
 2 interface PCI{
 3     public void open();
 4     public void close();
 5 }
 6 
 7 class MainBoard{
 8     public void run(){
 9         System.out.println("mainboard run");
10     }
11     public void usePCI(PCI p)
12     {
13         //以防空指针报错
14         if(p!=null)
15         {
16             p.open();
17             p.close();
18         }
19     }
20 }
21 
22 class NetCard implements PCI{
23     public void open(){
24         System.out.println("netcard open");
25     }
26     public void close(){
27         System.out.println("netcard close");
28     }
29 }
30 
31 class SoundCard implements PCI{
32     public void open(){
33         System.out.println("Soundcard open");
34     }
35     public void close(){
36         System.out.println("Soundcard close");
37     }
38 }
39 
40 public class DuoTaiDemo5 {
41     public static void main(String[] args) {
42     MainBoard mb=new MainBoard();
43     mb.run();
44     mb.usePCI(null);
45     mb.usePCI(new NetCard());
46     mb.usePCI(new SoundCard());
47    }
48 }

6.3、instanceof

判断一个对象到底是那个类的实例

对象 instanceof 类,返回值为boolean

7、object类

所有对象的间接父类。

其中方法多被重写使用

7.1、equals

boolean equals(Object obj)

 1 package learn;
 2 class Demo{
 3     private int num;
 4     Demo(){//重载
 5         
 6     }
 7     Demo(int num){
 8         this.num=num;
 9     }
10     public boolean equals(Object obj){//Object obj=new Object();
11         if(!(obj instanceof Demo))
12             return false;
13         //多态-向下转型
14         Demo d=(Demo)obj;
15         return this.num==d.num;
16     }
17 }
18 class Person{
19     
20 }
21 public class ObjectDemo {
22     public static void main(String[] args) {
23         Demo d1=new Demo();
24         Demo d2=new Demo();
25         System.out.println(d1.equals(d2));
26         Demo d3=new Demo(4);
27         Demo d4=new Demo(5);
28         Person p=new Person();
29         System.out.println(d3.equals(p));
30 }
31 }

7.2、toString

其实就是返回一个字符串,该字符串由类名+@+此对象哈希码的无符号十六进制表示组成。

getClass().getName() + '@' + Integer.toHexString(hashCode())
 1 public class ObjectDemo {
 2     public static void main(String[] args) {
 3 //        Demo d1=new Demo();
 4 //        Demo d2=new Demo();
 5 //        System.out.println(d1.equals(d2));
 6 //        Demo d3=new Demo(4);
 7 //        Demo d4=new Demo(5);
 8 //        Person p=new Person();
 9 //        System.out.println(d3.equals(p));
10         Demo d1=new Demo(4);
11         Class c=d1.getClass();
12         System.out.println(c.getName());
13         System.out.println(Integer.toHexString(d1.hashCode()));
14         System.out.println(d1.toString());
15 }
16 }
原文地址:https://www.cnblogs.com/sunxlfree1206/p/4666034.html