package com.atguigu.java; /* * abstract关键字的使用 * 1.abstract:抽象的 * 2.abstract可以用来修饰的结构:类、方法 * * 3. abstract修饰类:抽象类 * > 此类不能实例化 * > 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程) * > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 * * * 4. abstract修饰方法:抽象方法 * > 抽象方法只有方法的声明,没有方法体 * > 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。 * > 若子类重写了父类中的所有的抽象方法后,此子类方可实例化 * 若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
* abstract使用上的注意点:
* 1.abstract不能用来修饰:属性、构造器等结构
*
* 2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类
*
*/ public class AbstractTest { public static void main(String[] args) { //一旦Person类抽象了,就不可实例化 // Person p1 = new Person(); // p1.eat(); } } abstract class Creature{ public abstract void breath(); } abstract class Person extends Creature{ String name; int age; public Person(){ } public Person(String name,int age){ this.name = name; this.age = age; } //不是抽象方法: // public void eat(){ // // } //抽象方法 public abstract void eat(); public void walk(){ System.out.println("人走路"); } } class Student extends Person{ public Student(String name,int age){ super(name,age); } public Student(){ } public void eat(){ System.out.println("学生多吃有营养的食物"); } @Override public void breath() { System.out.println("学生应该呼吸新鲜的没有雾霾的空气"); } }
package com.atguigu.exer1; /* * 编写一个Employee类,声明为抽象类, 包含如下三个属性:name,id,salary。 提供必要的构造器和抽象方法:work()。 * * */ public abstract class Employee { private String name; private int id; private double salary; public Employee() { super(); } public Employee(String name, int id, double salary) { super(); this.name = name; this.id = id; this.salary = salary; } public abstract void work(); }
package com.atguigu.exer1; /* * 对于Manager类来说,他既是员工,还具有奖金(bonus)的属性。 */ public class Manager extends Employee{ private double bonus;//奖金 public Manager(double bonus) { super(); this.bonus = bonus; } public Manager(String name, int id, double salary, double bonus) { super(name, id, salary); this.bonus = bonus; } @Override public void work() { System.out.println("管理员工,提供公司运行的效率"); } }
package com.atguigu.exer1; public class CommonEmployee extends Employee { @Override public void work() { System.out.println("员工在一线车间生产产品"); } }
package com.atguigu.exer1; /* * 请使用继承的思想,设计CommonEmployee类和Manager类,要求类中提供必要的方法进行属性访问。 */ public class EmployeeTest { public static void main(String[] args) { //多态 Employee manager = new Manager("库克", 1001, 5000, 50000); manager.work(); CommonEmployee commonEmployee = new CommonEmployee(); commonEmployee.work(); } }
package com.atguigu.java; /* * 抽象类的匿名子类 * */ public class PersonTest { public static void main(String[] args) { method(new Student());//匿名对象 Worker worker = new Worker(); method1(worker);//非匿名的类非匿名的对象 method1(new Worker());//非匿名的类匿名的对象 System.out.println("********************"); //创建了一匿名子类的对象:p Person p = new Person(){ @Override public void eat() { System.out.println("吃东西"); } @Override public void breath() { System.out.println("好好呼吸"); } }; method1(p); System.out.println("********************"); //创建匿名子类的匿名对象 method1(new Person(){ @Override public void eat() { System.out.println("吃好吃东西"); } @Override public void breath() { System.out.println("好好呼吸新鲜空气"); } }); } public static void method1(Person p){ p.eat(); p.breath(); } public static void method(Student s){ } } class Worker extends Person{ @Override public void eat() { } @Override public void breath() { } }
package com.atguigu.java; /* * 抽象类的应用:模板方法的设计模式 * */ public class TemplateTest { public static void main(String[] args) { SubTemplate t = new SubTemplate(); t.spendTime(); } } abstract class Template{ //计算某段代码执行所需要花费的时间 public void spendTime(){ long start = System.currentTimeMillis(); this.code();//不确定的部分、易变的部分 long end = System.currentTimeMillis(); System.out.println("花费的时间为:" + (end - start)); } public abstract void code(); } class SubTemplate extends Template{ @Override public void code() { for(int i = 2;i <= 1000;i++){ boolean isFlag = true; for(int j = 2;j <= Math.sqrt(i);j++){ if(i % j == 0){ isFlag = false; break; } } if(isFlag){ System.out.println(i); } } } }
package com.atguigu.java; //抽象类的应用:模板方法的设计模式 public class TemplateMethodTest { public static void main(String[] args) { BankTemplateMethod btm = new DrawMoney(); btm.process(); BankTemplateMethod btm2 = new ManageMoney(); btm2.process(); } } abstract class BankTemplateMethod { // 具体方法 public void takeNumber() { System.out.println("取号排队"); } public abstract void transact(); // 办理具体的业务 //钩子方法 public void evaluate() { System.out.println("反馈评分"); } // 模板方法,把基本操作组合到一起,子类一般不能重写 public final void process() { this.takeNumber(); this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码 this.evaluate(); } } class DrawMoney extends BankTemplateMethod { public void transact() { System.out.println("我要取款!!!"); } } class ManageMoney extends BankTemplateMethod { public void transact() { System.out.println("我要理财!我这里有2000万美元!!"); } }
package com.atguigu.exer2; import java.util.Calendar; import java.util.Scanner; /* * 定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。 * 利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday。 * 当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。 */ public class PayrollSystem { public static void main(String[] args) { //方式一: // Scanner scanner = new Scanner(System.in); // System.out.println("请输入当月的月份:"); // int month = scanner.nextInt(); //方式二: Calendar calendar = Calendar.getInstance(); int month = calendar.get(Calendar.MONTH);//获取当前的月份 // System.out.println(month);//一月份:0 Employee[] emps = new Employee[2]; emps[0] = new SalariedEmployee("马森", 1002,new MyDate(1992, 4, 28),10000); emps[1] = new HourlyEmployee("潘雨生", 2001, new MyDate(1991, 5, 6),60,240); for(int i = 0;i < emps.length;i++){ System.out.println(emps[i]); double salary = emps[i].earnings(); System.out.println("月工资为:" + salary); if((month+1) == emps[i].getBirthday().getMonth()){ System.out.println("生日快乐!奖励100元"); } } } }
package com.atguigu.exer2; /* * 定义一个Employee类,该类包含: private成员变量name,number,birthday,其中birthday 为MyDate类的对象; abstract方法earnings(); toString()方法输出对象的name,number和birthday。 * */ public abstract class Employee { private String name; private int number; private MyDate birthday; public abstract double earnings(); public Employee(String name, int number, MyDate birthday) { super(); this.name = name; this.number = number; this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public MyDate getBirthday() { return birthday; } public void setBirthday(MyDate birthday) { this.birthday = birthday; } @Override public String toString() { return "name=" + name + ", number=" + number + ", birthday=" + birthday.toDateString() + "]"; } }
package com.atguigu.exer2; /* * MyDate类包含: private成员变量year,month,day ; toDateString()方法返回日期对应的字符串:xxxx年xx月xx日 */ public class MyDate { private int year; private int month; private int day; public MyDate(int year, int month, int day) { super(); this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public String toDateString(){ return year + "年" + month + "月" + day + "日"; } }
package com.atguigu.exer2; /* * 定义SalariedEmployee类继承Employee类, * 实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary; 实现父类的抽象方法earnings(),该方法返回monthlySalary值; toString()方法输出员工类型信息及员工的name,number,birthday。 */ public class SalariedEmployee extends Employee{ private double monthlySalary;//月工资 public SalariedEmployee(String name, int number, MyDate birthday) { super(name, number, birthday); } public SalariedEmployee(String name, int number, MyDate birthday,double monthlySalary) { super(name, number, birthday); this.monthlySalary = monthlySalary; } public double getMonthlySalary() { return monthlySalary; } public void setMonthlySalary(double monthlySalary) { this.monthlySalary = monthlySalary; } @Override public double earnings() { return monthlySalary; } public String toString(){ return "SalariedEmployee[" + super.toString() + "]"; } }
package com.atguigu.exer2; /* * 参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括: private成员变量wage和hour; 实现父类的抽象方法earnings(),该方法返回wage*hour值; toString()方法输出员工类型信息及员工的name,number,birthday。 */ public class HourlyEmployee extends Employee{ private int wage;//每小时的工资 private int hour;//月工作的小时数 public HourlyEmployee(String name, int number, MyDate birthday) { super(name, number, birthday); } public HourlyEmployee(String name, int number, MyDate birthday,int wage,int hour) { super(name, number, birthday); this.wage = wage; this.hour = hour; } public int getWage() { return wage; } public void setWage(int wage) { this.wage = wage; } public int getHour() { return hour; } public void setHour(int hour) { this.hour = hour; } @Override public double earnings() { return wage * hour; } public String toString(){ return "HourlyEmployee[" + super.toString() + "]"; } }
接 口:概述
一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方
法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又
没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打
印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都
支持USB连接。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则
必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是 "能不能"
的关系。
接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都
要遵守。
package com.atguigu.java1; /* * 接口的使用 * 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能定义全局常量和抽象方法 * >全局常量:public static final的.但是书写时,可以省略不写 * >抽象方法:public abstract的 * * 3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略) * * 4. 接口中不能定义构造器的!意味着接口不可以实例化 * * 5. Java开发中,接口通过让类去实现(implements)的方式来使用. * 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化 * 如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类 * * 6. Java类可以实现多个接口 --->弥补了Java单继承性的局限性 * 格式:class AA extends BB implements CC,DD,EE * * 7. 接口与接口之间可以继承,而且可以多继承 * * ******************************* * 8. 接口的具体使用,体现多态性 * 9. 接口,实际上可以看做是一种规范 * * 面试题:抽象类与接口有哪些异同? * */ public class InterfaceTest { public static void main(String[] args) { System.out.println(Flyable.MAX_SPEED); System.out.println(Flyable.MIN_SPEED); // Flyable.MIN_SPEED = 2; Plane plane = new Plane(); plane.fly(); } } interface Flyable{ //全局常量 public static final int MAX_SPEED = 7900;//第一宇宙速度 int MIN_SPEED = 1;//省略了public static final //抽象方法 public abstract void fly(); //省略了public abstract void stop(); //Interfaces cannot have constructors // public Flyable(){ // // } } interface Attackable{ void attack(); } class Plane implements Flyable{ @Override public void fly() { System.out.println("通过引擎起飞"); } @Override public void stop() { System.out.println("驾驶员减速停止"); } } abstract class Kite implements Flyable{ @Override public void fly() { } } class Bullet extends Object implements Flyable,Attackable,CC{ @Override public void attack() { // TODO Auto-generated method stub } @Override public void fly() { // TODO Auto-generated method stub } @Override public void stop() { // TODO Auto-generated method stub } @Override public void method1() { // TODO Auto-generated method stub } @Override public void method2() { // TODO Auto-generated method stub } } //************************************ interface AA{ void method1(); } interface BB{ void method2(); } interface CC extends AA,BB{ }
package com.atguigu.java1; /* * 接口的应用:代理模式 * */ public class NetWorkTest { public static void main(String[] args) { Server server = new Server(); // server.browse(); ProxyServer proxyServer = new ProxyServer(server); proxyServer.browse(); } } interface NetWork{ public void browse(); } //被代理类 class Server implements NetWork{ @Override public void browse() { System.out.println("真实的服务器访问网络"); } } //代理类 class ProxyServer implements NetWork{ private NetWork work; public ProxyServer(NetWork work){ this.work = work; } public void check(){ System.out.println("联网之前的检查工作"); } @Override public void browse() { check(); work.browse(); } }
package com.atguigu.java1; public class StaticProxyTest { public static void main(String[] args) { Proxy s = new Proxy(new RealStar()); s.confer(); s.signContract(); s.bookTicket(); s.sing(); s.collectMoney(); } } interface Star { void confer();// 面谈 void signContract();// 签合同 void bookTicket();// 订票 void sing();// 唱歌 void collectMoney();// 收钱 } //被代理类 class RealStar implements Star { public void confer() { } public void signContract() { } public void bookTicket() { } public void sing() { System.out.println("明星:歌唱~~~"); } public void collectMoney() { } } //代理类 class Proxy implements Star { private Star real; public Proxy(Star real) { this.real = real; } public void confer() { System.out.println("经纪人面谈"); } public void signContract() { System.out.println("经纪人签合同"); } public void bookTicket() { System.out.println("经纪人订票"); } public void sing() { real.sing(); } public void collectMoney() { System.out.println("经纪人收钱"); } }
package com.atguigu.java1; interface A { int x = 0; } class B { int x = 1; } class C extends B implements A { public void pX() { //编译不通过。因为x是不明确的 // System.out.println(x); System.out.println(super.x);//1 System.out.println(A.x);//0 } public static void main(String[] args) { new C().pX(); } }
package com.atguigu.java1; interface Playable { void play(); } interface Bounceable { void play(); } interface Rollable extends Playable, Bounceable { Ball ball = new Ball("PingPang"); } class Ball implements Rollable { private String name; public String getName() { return name; } public Ball(String name) { this.name = name; } public void play() { //这里同时重写Playable、Bounceable接口的play方法 // ball = new Ball("Football"); //The final field Rollable.ball cannot be assigned System.out.println(ball.getName()); } }
package com.atguigu.exer3; public class ComparableCircleTest { public static void main(String[] args) { ComparableCircle c1 = new ComparableCircle(3.4); ComparableCircle c2 = new ComparableCircle(3.6); int compareValue = c1.compareTo(c2); if(compareValue > 0){ System.out.println("c1对象大"); }else if(compareValue < 0){ System.out.println("c2对象大"); }else{ System.out.println("c1与c2一样大"); } int compareValue1 = c1.compareTo(new String("AA")); System.out.println(compareValue1); } }
package com.atguigu.exer3; /* * 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。 * 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。 */ public class ComparableCircle extends Circle implements CompareObject{ public ComparableCircle(double radius) { super(radius); } @Override public int compareTo(Object o) { if(this == o){ return 0; } if(o instanceof ComparableCircle){ ComparableCircle c = (ComparableCircle)o; //错误的: // return (int) (this.getRadius() - c.getRadius()); //正确的方式一: // if(this.getRadius() > c.getRadius()){ // return 1; // }else if(this.getRadius() < c.getRadius()){ // return -1; // }else{ // return 0; // } //当属性radius声明为Double类型时,可以调用包装类的方法 //正确的方式二: return this.getRadius().compareTo(c.getRadius()); }else{ // return 0; throw new RuntimeException("传入的数据类型不匹配"); } } }
package com.atguigu.exer3; /* * interface CompareObject{ public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小 } */ public interface CompareObject { //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小 public int compareTo(Object o); }
package com.atguigu.exer3; /* * 定义一个Circle类,声明radius属性,提供getter和setter方法 */ public class Circle { private Double radius; public Double getRadius() { return radius; } public void setRadius(Double radius) { this.radius = radius; } public Circle() { super(); } public Circle(Double radius) { super(); this.radius = radius; } }
package com.atguigu.java8; public class SubClassTest { public static void main(String[] args) { SubClass s = new SubClass(); // s.method1(); // SubClass.method1(); //知识点1:接口中定义的静态方法,只能通过接口来调用。 CompareA.method1(); //知识点2:通过实现类的对象,可以调用接口中的默认方法。 //如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法 s.method2(); //知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法, //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则 //知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法, //那么在实现类没有重写此方法的情况下,报错。-->接口冲突。 //这就需要我们必须在实现类中重写此方法 s.method3(); } } class SubClass extends SuperClass implements CompareA,CompareB{ public void method2(){ System.out.println("SubClass:上海"); } public void method3(){ System.out.println("SubClass:深圳"); } //知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法 public void myMethod(){ method3();//调用自己定义的重写的方法 super.method3();//调用的是父类中声明的 //调用接口中的默认方法 CompareA.super.method3(); CompareB.super.method3(); } }
package com.atguigu.java8; /* * * JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法 * */ public interface CompareA { //静态方法 public static void method1(){ System.out.println("CompareA:北京"); } //默认方法 public default void method2(){ System.out.println("CompareA:上海"); } default void method3(){ System.out.println("CompareA:上海"); } }
package com.atguigu.java8; public interface CompareB { default void method3(){ System.out.println("CompareB:上海"); } }
package com.atguigu.java8; public class SuperClass { public void method3(){ System.out.println("SuperClass:北京"); } }
package com.atguigu.java8; interface Filial {// 孝顺的 default void help() { System.out.println("老妈,我来救你了"); } } interface Spoony {// 痴情的 default void help() { System.out.println("媳妇,别怕,我来了"); } } class Father{ public void help(){ System.out.println("儿子,救我媳妇!"); } } class Man extends Father implements Filial, Spoony { @Override public void help() { System.out.println("我该救谁呢?"); Filial.super.help(); Spoony.super.help(); } }
package com.atguigu.java2; /* * 类的内部成员之五:内部类 * 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类 * * 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内) * * 3.成员内部类: * 一方面,作为外部类的成员: * >调用外部类的结构 * >可以被static修饰 * >可以被4种不同的权限修饰 * * 另一方面,作为一个类: * > 类内可以定义属性、方法、构造器等 * > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承 * > 可以被abstract修饰 * * * 4.关注如下的3个问题 * 4.1 如何实例化成员内部类的对象 * 4.2 如何在成员内部类中区分调用外部类的结构 * 4.3 开发中局部内部类的使用 见《InnerClassTest1.java》 * */ public class InnerClassTest { public static void main(String[] args) { //创建Dog实例(静态的成员内部类): Person.Dog dog = new Person.Dog(); dog.show(); //创建Bird实例(非静态的成员内部类): // Person.Bird bird = new Person.Bird();//错误的 Person p = new Person(); Person.Bird bird = p.new Bird(); bird.sing(); System.out.println(); bird.display("黄鹂"); } } class Person{ String name = "小明"; int age; public void eat(){ System.out.println("人:吃饭"); } //静态成员内部类 static class Dog{ String name; int age; public void show(){ System.out.println("卡拉是条狗"); // eat(); //静态加载找不能调用非静态类的方法 } } //非静态成员内部类 class Bird{ String name = "杜鹃"; public Bird(){ } public void sing(){ System.out.println("我是一只小小鸟"); Person.this.eat();//调用外部类的非静态属性 eat(); System.out.println(age); } public void display(String name){ System.out.println(name);//方法的形参 System.out.println(this.name);//内部类的属性 System.out.println(Person.this.name);//外部类的属性 } } public void method(){ //局部内部类 class AA{ } } { //局部内部类 class BB{ } } public Person(){ //局部内部类 class CC{ } } }
package com.atguigu.java2; public class InnerClassTest1 { //开发中很少见 public void method(){ //局部内部类 class AA{ } } //返回一个实现了Comparable接口的类的对象 public Comparable getComparable(){ //创建一个实现了Comparable接口的类:局部内部类 //方式一: // class MyComparable implements Comparable{ // // @Override // public int compareTo(Object o) { // return 0; // } // // } // // return new MyComparable(); //方式二: return new Comparable(){ @Override public int compareTo(Object o) { return 0; } }; } }