java面向对象编程之part03

    技术2024-07-25  17

    目录

     

    掌握多态的原理,发生多态的条件和多态使用场合

    掌握向下转型和向上转型,以及instanceof运算符的使用

    掌握final关键字的使用

    object类中的常见方法

    掌握抽象类和抽象方法的特点和使用

    掌握接口的定义与实现

    接口与抽象类的区别

    掌握比较器的运用


    掌握多态的原理,发生多态的条件和多态使用场合

    java实现多态有三个前提条件:

    1.子类继承父类或是子类实现接口:

            在多态中必须存在继承关系的子类或者实现了接口的子类;

    2.重写方法:

            重写父类的方法,运行时多态会调用子类的重写方法;

    3.向上转型:

           在多态中需要将子类的引用赋值给父类的类型,这样才能够根据引用的类型调用相对应子类的方法;

    掌握向下转型和向上转型,以及instanceof运算符的使用

    向上转型一定是安全的,子类对象赋值给父类引用或接口引用;

    向下转型最好先使用instanceof进行判断一下是否可转;

    instanceof语法:对象引用   instanceof    父类或接口类型;

    public class Test { public static void main(String[] args) { Person a = new Student(); //向上转型 Person b = new Teacher(); //向上转型 //在进行转型之前先用instanceof关键字判断一下该引用是否是该类型或者其子类型 if (a instanceof Student){ Student s = (Student)a; //向下转型 Student s1 = (Teacher)b; //兄弟类之间不可互转 } } } class Person{ } class Student extends Person{ } class Teacher extends Person{ }

    掌握final关键字的使用

    1.final修饰的变量不可变,也就是常量,此时常量名一般大写;

    2.final修饰的方法不可被重写,但可以被重载;

    3.final修饰的类不可以被继承;

    4.final不能修饰抽象类;

    object类中的常见方法

    object是java中所有类的父类;

    常见方法有:

    protected Objectclone()

    创建并返回此对象的副本。

    booleanequals(Object obj)

    指示一些其他对象是否等于此。

    protected voidfinalize()

    当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。

    类<?>getClass()

    返回此 Object的运行时类。

    inthashCode()

    返回对象的哈希码值。

    voidnotify()

    唤醒正在等待对象监视器的单个线程。

    voidnotifyAll()

    唤醒正在等待对象监视器的所有线程。

    StringtoString()

    返回对象的字符串表示形式。

    voidwait()

    导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。

    voidwait(long timeout)

    导致当前线程等待,直到另一个线程调用 notify()方法或该对象的 notifyAll()方法,或者指定的时间已过。

    voidwait(long timeout, int nanos)

    导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法,或者某些其他线程中断当前线程,或一定量的实时时间。

     

    掌握抽象类和抽象方法的特点和使用

    1.抽象类和抽象方法都要用abstract关键字修饰;

    2.抽象类不可被实例化,通俗来讲就是不能new对象;

    3.抽象类中可以没有或有一个或多个抽象方法,甚至全是抽象方法也行;抽象类可以有非抽象方法;

    4.抽象方法只有方法声明,没有方法实现,有抽象方法的类必须用abstract修饰,继承抽象类后必须重写全部的抽象方法,否则子类依旧是一个抽象类,不能实例化;

    掌握接口的定义与实现

    接口:

    [修饰符]  interface  接口名  extends  父接口1, 父接口2...{

    零个到多个常量定义...

    零个到多个抽象方法定义...

    零个到多个内部类、接口、枚举定义...

    零个到多个默认方法或类方法定义...

    //java9 新增的(零个到多个私有方法定义...)

    }

    注:

    1.接口中可以含有常量和方法;接口中的常量只能是public static final 修饰,用其他的会报错;(jdk1.8中)方法只能是public abstract或者default修饰,用其他的会报错如:private,protected,static,final;

    2.接口中的方法必须都是抽象方法;

    3.允许一个类实现多个接口;允许一个接口继承多个接口;一个接口继承多个父接口时,多个父接口排在extends关键字之后,多个父接口之间用英文(,)隔开。

    4.实现接口方法时,必须使用public访问控制符,因为接口里的方法都是public的,而子类(相当于实现类)重写父类方法时访问权限只能更大或者相等,所以实现类实现接口里的方法只能使用public访问权限。

    接口与抽象类的区别

    相似:

    1.接口和抽象类都不能被实例化;

    2.接口和抽象类都可以包含抽象方法;

    不同点:

    1.接口中除了默认方法跟私有方法,其他方法不能有方法体,抽象类则可以有任意方法;

    2.接口中只能定义静态常量,而抽象类中可以定义任意类型的变量,

    3.接口内不能构造方法;抽象类中可以有构造方法;

    4.接口中不可以含有静态代码块和静态方法,而抽象类中可以含有;

    掌握比较器的运用

    java中的比较器大概分为内部比较器和外部比较器;

    下面是测试类;

    import java.util.ArrayList; import java.util.List; /* * 题一:调用Collections.sort()方法,通过定值排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递 * 分析: * 1.定制排序:指自定义比较器|定制排序 * 自然排序:内部比较器|自然排序 * 2.先比较年龄,年龄相同才比较姓名 */ public class TestLambda01 { public static void main(String[] args) { List<Employee> list = new ArrayList(); list.add(new Employee("aaa",12)); list.add(new Employee("fff",55)); list.add(new Employee("sss",66)); list.add(new Employee("bbb",22)); System.out.println(list); // Collections.sort(list);//内部比较器 // System.out.println(list); // Collections.sort(list,new MyCompare());//外部比较器 // System.out.println(list); } }

     下面是雇员类;

    import java.util.Objects; public class Employee implements Comparable{ private String name; private int age; @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return age == employee.age && Objects.equals(name, employee.name); } @Override public int hashCode() { return Objects.hash(name, 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 Employee(String name, int age) { this.name = name; this.age = age; } public Employee() { } @Override public int compareTo(Object o) { Employee e = (Employee)o; if(this.age > e.age){ return 1; }else if(this.age < e.age){ return -1; }else { return this.name.compareTo(e.name); } } }

     下面是自定义的外部比较器,实现Comparator接口;

    import java.util.Comparator; public class MyCompare implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { if(o1.getAge() > o2.getAge()){ return 1; }else if(o1.getAge() < o2.getAge()){ return -1; }else { return o1.getName().compareTo(o2.getName()); } } }

    了解内部类的定义和特点

    内部类分为静态内部类,局部内部类,成员内部类,匿名内部类

    一个类定义在另一个类的内部就是内部类;

    public class Outer { private String str1 = "成员内部类"; static String str2 = "静态内部类"; public void pr(){ String str = "aaa"; System.out.println(str); } class Inner{ public Inner() { } public String getName(){ return str1; //成员内部类可以直接访问外部类的所有变量 } } static class Inner2{ public String getAge(){ return str2; //静态内部类只能直接访问外部类的静态变量 } } interface Hello{ void getAaa(); } public void sayHello(){ class MyHello implements Hello{ final String aaa = "局部内部类"; //局部内部类 @Override public void getAaa() { System.out.println(aaa); } } Hello h = new Hello() { final String bbb = "匿名内部类"; //匿名内部类 @Override public void getAaa() { System.out.println(bbb); } }; MyHello myHello = new MyHello(); myHello.getAaa(); h.getAaa(); } }

    测试类test.java

    public class Test { public static void main(String[] args) { Outer.Inner oi = new Outer().new Inner(); //成员内部类 System.out.println(oi.getName()); Outer.Inner2 oi2 = new Outer.Inner2(); //静态内部类 System.out.println(oi2.getAge()); Outer o = new Outer(); o.sayHello(); } }

     

     

     

     

     

    Processed: 0.012, SQL: 9