黑马程序员 java学习笔记——面向对象3:多态(含内部类)

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

概述

多态的概念:可以理解为事物存在的多种体现形态。
1、 多态的体现:
父类的引用指向了自己的子类对象
父类的引用也可以接受子类对象。
2、 多态的前提
必须是类与类之间有关系,要么继承,要么实现
3、 多态的好处
大大提高了程序的扩展性
4、 多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5、多态的应用
示例代码如下:
class Student{
	public abstract void study();
	public void sleep(){
		System.out.println("躺着睡");
	}
}
class DoStudent{
	public void dosome(Student stu){
		stu.study();
		stu.sleep();
	}
}
class BaseStudent extends Student{
	public void study(){
		System.out.println("base study");
	}
	public void sleep(){
				System.out.println("坐着睡");
	}
}
class AdvStudent extends Student{
	public void study(){
		System.out.println("adv study");
	}
}
public class Demo{
	public static void main(String[] args){
		BaseStudent bs=new BaseStudent();
		bs.study();
		bs.sleep();
		AdvStudent bs=new AdvStudent();
		as.study();
		as.sleep();

		DoStudent ds=new DoStudent();
		ds.dosome(new BaseStudent());
		ds.dosome(new BaseStudent());		
	}
}


成员的特点

1、成员变量

编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。
运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
简单总结:编译和运行都参考等号的左边。

2、成员函数(非静态)

编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
简单总结:编译看左边,运行看右边。因为成员函数存在覆盖特性。

3、静态函数

编译时:参考引用型变量所属的类中的是否有调用的静态方法。
运行时:参考引用型变量所属的类中的是否有调用的静态方法。
其实对于静态方法,是不需要对象的。直接用类名调用即可。
简单总结:编译和运行都看左边。

4、总结

非静态成员函数,编译时看左边,运行时看右边。其他都看左边。

多态的主板示例

interface PCI{
        public abstract void open();
        public abstract void close();
}
class MainBoard{
        public void run(){
                System.out.println("mainboard run");
        }
        public void usePCI(PCI p){
                if(p!=null){
                        p.open();
                        p.close();
                }
        }
}
class NetCard implements PCI{
        public void open(){
                System.out.println("netcard open");
        }
        public void close(){
                System.out.println("netcard close");
        }
}
class SoundCard implements PCI{
        public void open(){
                System.out.println("soundcard open");
        }
        public void close(){
                System.out.println("soundcard close");
        }
}
public class Demo{
        public static void main(String[] args){
                MainBoard mb=new MainBoard();
                mb.run();
                mb.usePCI(null);
                mb.usePCI(new NetCard());
                mb.usePCI(new SoundCard());
        }        
}

多态的扩展示例

interface UserInfoDao{
	public void add(User user);
	public void delete(User user);
}
class UserInfoByJDBC implements UserInfoDao{
	public void add(User user){
		1、JDBC连接数据库
		2、使用sql添加语句添加数据
		3、关闭连接
	}
	public void delete(User user){
		1、JDBC连接数据库
		2、使用sql添加语句删除数据
		3、关闭连接
	}
}
class DBOperate{
	public static void main(String[] args){
		UserInfoDao ui=new UserInfoByJDBC();
		ui.add(user);
		ui.delete(user);
	}
}

Object类中方法示例

class Demo{  //extends Object
	private int num;
	Demo(){}
	Demo(int num){
		this.num=num;
	}
	public boolean equals(Object obj){ Object obj=new Demo();
		if(!(obj instanceOf Demo))
			return false;
		Demo d=(Demo)obj;
		return this.num==obj.num;
	}
	public String toString(){
		return "demo:"+num;
	}
}
public class ObjectDemo{
	public static void main(String[] args){
		Demo d1=new Demo();
		Demo d2=new Demo();
		Demo d3=d1;
		System.out.println(d1.euqals(d3));
		System.out.println(d1==d2);
		System.out.println(d1==d3);

		Demo d4=new Demo(9);
		Demo d5=new Demo(9);
		System.out.println(d4.euqals(d5));
		System.out.println(d4);
	}
}

内部类

概念:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
内部类的 访问规则
1、内部类可以直接访问外部类中的成员,包括私有成员。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2、外部类要访问内部类,必须建立内部类对象。
访问内部类的 格式
1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。
格式:外部类名.内部类名 变量名=外部类对象.内部类对象
示例代码如下:
class Outer{
    private int x=1;//想要让内部类访问到这个,需要将function中的x改成Outer.this.x
                    //如果内部类没有与x重名的变量,那么省略Outer.this也行,前面会默认添加。
    class Inner{
            int x=2;  //想要访问到Inner的成员变量x,function中的打印语句中的x需要改成this.x
            public void function(){
                    int x=3;  
                    System.out.println("Inner:"+this.x);
            }
    }
    void method(){
            Inner in=new Inner();
            in.function();
    }
}
public class Demo{
    public static void main(String[] args){
            Outer out=new Outer();
            out.method();

            /*
            //直接访问内部类中的成员
            Outer.Inner in=new Outer().new Inner();   //内部类直接创建对象的方式
            in.function();
            */
    }
}

2、当内部类在成员位置上,就可以被成员修饰符所修饰
比如:private:将内部类在外部类中进行封装。
static:内部类就具备被static的特性。
当内部类被静态static修饰后,只能直接访问外部类中的static成员,出现了访问局限
在外部其他类中,如何直接访问static内部类的非静态呢?
示例代码如下:
class Outer{
	private static int x=3;
	static class Inner{
		void function(){
			System.out.println("inner:"+x);
		}
	}
}
class Demo{
	public class void main(String[] args){
		new Outer.Inner().function();
	}
}

在外部其他类中,如何直接访问static内部类的静态呢?

示例代码如下:

class Outer{
	private static int x=3;
	static class Inner{
		static void function(){
			System.out.println("inner:"+x);
		}
	}
}
class Demo{
	public class void main(String[] args){
		Outer.Inner.function();
	}
}


注意:1、当内部类中定义了静态static成员,该内部类必须是静态static的2、当外部类中的静态方法访问内部类时,内部类也必须是静态的。示例代码如下:

class Outer{
	private static int x=3;
	static class Inner{
		void function(){
			System.out.println("inner:"+x);
		}
	}
}
class Demo{
	public class void main(String[] args){
		new Outer.Inner().function();
	}
}
class Outer{
	private static int x=3;
	static class Inner{
		static void function(){
			System.out.println("inner:"+x);
		}
	}
	class Inner2{
		void show(){
			System.out.println("inner2 show");
		}
	}
	public static void method(){
		Inner.function();
	}
}
class Demo{
	public class void main(String[] args){
		
	}
}

内部类定义原则:当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容。

匿名内部类

1、匿名内部类其实就是内部类的简写格式
2、定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
匿名内部类其实就是匿名子类对象。
匿名内部类的方法不要超过3个,不利于阅读。
匿名内部类的用法:作为参数传入方法
示例代码如下:

interface Inter{
	void method();
}

class Test{
	//补足代码
	static Inter function(){
		return new Inter();
		public void method(){
			System.out.println("method run");
		}
	}
}
public class Demo{
	public static void main(String[] args){
		//Test.function():Test类中有一个静态的方法fuction
		//method方法:function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象
		//因为只有是Inter类型的对象,才可以调用method方法。
		Test.function().method();

		show(new Inter(){
			public void method(){
				System.out.println("method show run");
			}
		});
	}
	public static void show(Inter in){
		in.method();
	}
}

----------------------  ASP.Net+Android+IO开发S .Net培训 、期待与您交流! ----------------------

你可能感兴趣的:(java基础)