基础回顾:
1.方法的重载
1.方法名称相同 2.方法的参数列表不同(参数个数,参数类型,参数顺序至少有一项) 3.方法的返回值类型和修饰符不做要求,可以相同也可以不同
2.构造方法
1.构造方法名称和其所属的类名必须保持一致 2.构造方法没有返回值,也不可以使用void关键字 3.可以用访问控制符 4.可以像普通函数一样被重载
5.构造方法不能被static和final修饰 6.构造方法不能被继承,子类使用父类的构造方法需要使用super关键字
3.构造方法的私有化
把构造方法设置为private,那么其他类中就无法调用该构造方法,不能使用new关键字调用该构造方法创建该类的实例化对象。
4.static方法
1.声明静态属性变量,称为静态变量,只有被static修饰的变量,才能被main函数引用
2.声明方法,也称为“类方法”,可以由类名直接调用
如果在类中声明了一个static类型的属性,则此属性既可以在非static类型的方法中使用,也可以在static类型的方法中使用,但若要用static类型的方法调用非static类型的属性,就会出现错误。
class Person{ String name; private static String nation = "美国"; public static void setNation(n){ this.nation = n; } public void print(){ system.out.println(this.nation);//报错,非static修饰函数不能调用static修饰的变量 } } public static void main(String[] args){ Person p; Person.setNation("中国")//可以直接由类名调用 }
3.理解主方法main()
Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为Java虚拟机在执行main()方法时不需要创建对象,所以该方法必须是static。
该方法接收一个String类型的数值参数,该数组中保存执行Java命令时传递给所运行的类的参数。
核心内容回顾:
1.封装
将描述某类事物的数据与处理这些数据的函数封装在一起,形成一个有机整体,称为类。
属性好比蛋黄,行为好比蛋白,接口好比蛋壳,外部只能通过公开的接口方法来改变对象内部的属性值,从而使类中数据的安全性得到保证。
2.继承
继承的目的在于是吸纳代码的重用,对已有的成熟的功能, 子类从父类执行“拿来主义”
Java中支持类的单继承和多层继承,但是不支持多继承,一个类只能继承一个类而不能继承多个类。
3.继承的限制
从父类继承的私有成员,不能被子类直接使用
被final修饰的方法不能被子类覆写实例,被final修饰的类不能再被继承,所以final被称为终结器(terminator)
4.子类覆写父类的属性和方法
如果子类定义的属性和方法名和父类相同,将覆盖父类定义的属性值和方法,从开发者的角度上来说,父类中的属性值一般是private看不见的,所以在设置子类属性的时候是一套新的属性,但是可以使用super来调用父类的方法
有时候可以在覆写的时候增加上“@Override”注解,@Override用在方法之上,就是显式搞事编译器,这个方法是用来覆写来自父类的同名方法,如果父类没有这个所谓“同名”的方法,就会发出警告信息。
5.多态
方法多态性:
方法重载:同一个方法名称,根据其传入的参数类型,个数和顺序的不同,调用的方法体也不同。
方法覆写:父类中的一个方法,在不同的子类有不同的实现功能,子类覆写父类方法。
对象多态性:
向上转型:父类对象通过子类对象去实例化,实际上就是对象的向上转型。Person p = new Student()
向下转型:父类对象可以转换为子类对象,但是必须使用强制类型转换。Person p = new Person(); Student s = new Student(); s = p
public class ObjectPoly{ public static void main(String[] args){ Animal a; Fish f = new Fish(); Bird b = new Bird(); Horse h = new Hose(); a = f; a.move();//向上转型,调用fish的move方法 a = b; a.move();//向上转型,调用fish的move方法 a = h; a.move();//向上转型,调用fish的move方法 } }
6.抽象类
一个类没有足够的信息来描述一个具体的对象,还需要其他具体的类来支撑它,那么这样的类称为抽象类。简单的说,就是Java中有一种类,派生出很多子类,而自身是不能用来产生对象的,这种类称为“抽象类”(有点类似模板)。
所谓抽象方法,就是只在什么而实现的方法。所有的抽象方法中,必须使用abstract,关键字声明,而包含抽象方法的类,就是抽象类,也必须使用abstract class声明。
抽象类规则; 1.抽象类和抽象方法都必须使用abstract关键字来修饰 2.抽象类不能直接实例化,也就是不能直接使用new关键字去产生对象 3.在抽象类中,定义时抽象方法只需声明,而无需实现 4.含有抽象方法的类必须被声明为抽象类,抽象类的子类必须实现所有的抽象方法后,才能不交抽象类,从而可以被实例化,否则这个子类还是个抽象类
抽象类的使用: 1.抽象类必须拥有子类,子类使用extends基础抽象类,一个子类只能继承一个抽象类 2.生成对象的子类,必须实现抽象类之中的全部抽象方法,只能所有抽象对象不再抽象了,才能生成实例化对象 3.如果想要实例化抽象类的对象,则可以通过子类进行对象的向上转型来完成
package text; abstract class Person_re { String name; int age; String occupation; public Person_re(String name,int age,String occupation) { this.age = age; this.name = name; this.occupation = occupation; } public abstract String talk(); } class Student_re extends Person_re{ public Student_re(String name,int age,String occupation){ super(name,age,occupation); } @Override public String talk() { // TODO Auto-generated method stub return "我叫:"+name+"今年:"+age+"岁,目前是一个"+occupation; } } class Worker extends Person_re{ public Worker(String name,int age,String occupation){ super(name,age,occupation); } @Override public String talk() { // TODO Auto-generated method stub return "我叫:"+name+"今年:"+age+"岁,目前是一个"+occupation; } } public class AbstractDemo{ public static void main(String agrs[]) { Student_re s = new Student_re("吉吉",10,"学生"); Person_re p = s; System.out.println(p.talk()); Worker w = new Worker("飘飘",20,"济公"); p = w; System.out.println(p.talk()); } } //这段代码在运行的时候出现了一个问题,代码的编译是一个包一起进行编译的,同一个包下的Java文件已经有了一个person对象,导致到这个文件里的person对象已经不起作用了,以后需要引起注意
7.接口
在Java中的一种机制,把对数据的通用操作(也就是方法),汇集在一起,形成一个接口,以形成复用。(类似于C语言中的结构体)接口是一种特殊的类,其结构和抽象类非常相似,是抽象类的一种变体。在接口内部定义一个变量时,系统会自动把“public static final”这三个关键字添加在变量前面(static表示全局变量,final表示变量初始化后不能再更改)所有接口的成员,其访问类型都必须为public,否则不能被继承。
public interface face A{ public (final) static int num = 1;//全局常量 public (abstract) void print();//抽象方法 default public void otherprint(){ .... }//带方法体的默认方法 }
使用接口的原则 1.接口必须有子类,子类依靠implement关键字可以同时实现多个接口。 2.接口的子类(如果不是抽象类),必须实现接口之中的全部抽象方法,才能实例化对象。 3.利用子类实现对象的实例化,接口可以实现多态性。 4.接口中除default方法外必须是抽象方法,所以abstract关键字可以省略,接口的数据成员必须赋初值,且不能再更改,所以可以省略关键字final
class 子类名称 implements 接口A,接口B{}
一个子类可以实现多个接口,这是间接实现多继承的一种机制。子类的继承体系中,永远只有一个父类,但子类却可以同时实现多个接口,变相完成多继承。
package text; interface InterfaceA{ public static String info = "static final";//省略final关键字,一定要赋初值 public void print();//省略abstract关键字 default public void otherprint() { System.out.println("print default methods InterfaceA"); } } class subClass implements InterfaceA{ @Override public void print() { // TODO Auto-generated method stub System.out.println("print abstract methods InterfaceA"); System.out.println(info); } } public class Interfacedefault { public static void main(String[] args) { // TODO Auto-generated method stub subClass s = new subClass(); s.print(); s.otherprint(); System.out.println(InterfaceA.info); } }
继承多个接口可以通过向上转型为父接口实例化,调用对应的实现方法。
继承多个接口时如果接口的默认方法名称相同,则不能通过编译,编译器不能识别选择要进行编译的方法,因此一个若一个类实现多个接口时,若接口中有默认方法,则不能出现同名默认方法。
事实上,Java之所以禁止多继承,是为了避免类似的二义性。但是在接口中允许实现默认方法,似乎又重新开启了“二义性”灾难之门。
在“变相”实现的多继承中,如果在一个子类中既要实现接口又要实现抽象类,则应该采用先继承后实现接口的顺序完成。
package text; interface faceA{ String info = "这是faceA的变量"; void print(); } interface faceB{ public abstract void get(); } abstract class abstractC{ public abstract void fun(); } class subclass extends abstractC implements faceA,faceB{ @Override public void print() { // TODO Auto-generated method stub System.out.println(info); }//实现接口a的方法 @Override public void get() { // TODO Auto-generated method stub System.out.println("这是实现 faceB"); }//实现接口b的方法 @Override public void fun() { // TODO Auto-generated method stub System.out.println("这是继承自abstractC"); }//实现抽象类c的方法 } public class ExtendInterface { public static void main(String[] args) { // TODO Auto-generated method stub subclass s = new subclass(); faceA fa = s; faceB fb = s; abstractC ac = s; fa.print(); fb.get(); ac.fun(); } }
修改继承和接口的实现顺序则会报错。
继承一个抽象类和继承一个普通类的主要区别:
1.在普通类之中所有的方法都是有方法体的,如果说有一些方法希望由子类实现的时候,子类即使不实现,也不会出现错误。而如果是重写改写了父类的同名方法,就是构成“覆写”。
2.如果使用抽象类的话,那么抽象类之中的抽象方法在语法规则上就必须要求子类给予实现,这样就可以强制子类做一些固定操作。