文章目录
封装
1.语法
使用private关键字,修饰字段和方法,只能在当前类中使用
意义:安全性,可复用性
继承
1.语法
class 子类 extends 父类{}
意义:提高代码复用性
-
在java中,只能通过extends来继承一个类
-
java中一个子类只能继承一个父类
-
子类会继承父类的所有的字段和方法
-
对于父类的private方法,子类是无法访问的
-
子类和父类有同名的属性,会优先调用子类中的属性。
class Animal{ public String name="haahah"; public int age; } class Dog extends Animal{ public String name="wangwang";//如果没有这一行,则输出结果为haahah public Dog(){ System.out.println(name); } } public class TestExtends { public static void main(String[] args) { Dog d=new Dog(); } } //输出结果:wangwang
-
引入super:父类对象的引用(必须写在子类构造方法的第一行)
- super.data //访问父类的成员变量
- super.func() //访问父类的成员方法
- super() //访问父类的成员的构造方法
-
子类继承父类之后,要想实例化子类对象,一定要先帮父类进行构造。所有构造对象,只能通过构造方法进行构造
- 所有类编译器会提供一个空参构造器,若自主的写入一个带参的构造方法,编译器不会再提供空参构造器
class Animal{ public String name="hahahah"; public int age; //提供了带参构造器 public Animal(String name,int age){ this.name=name; this.age=age; } public void test(){ System.out.println(name+"今年"+age+"岁了"); } } class Dog extends Animal{ public String name; //子类也要提供带参构造器 public Dog(String name,int age){ super(name,age);//必须写在第一行 } }
-
注:继承最好不要超过3层,可以使用final修饰类,该类不能被继承了
class A{ public int age=10; } class B extends A{ public int age=20; } //final修饰类,成密封类 final class C extends B{ public void func(){ System.out.println(super.age);//这里的super只指直接父类B } }
多态
1.1向上转型
Animal animal=new Dog("xiugou",10);
向上转型之后,只能通过父类引用访问父类的属性和方法,不能访问子类特有的属性和方法:swimming()是Dog子类特有的方法
class Animal{
public String name;
public int age;
public Animal(String name,int age){
this.name=name;
this.age=age;
}
}
class Dog extends Animal{
public String name;
public Dog(String name,int age){
super(name,age);
}
public void swimming(){
System.out.println(name+"游泳~");
}
}
public static void main(String[] args) {
Animal animal=new Dog("xiugou",10);
//animal.swimming();//编译错误
}
向上转型发生时机:
①直接赋值 Animal animal=new Dog("xiugou",10);
②传参
class Animal{
public void message(){
System.out.println("Animal");
}
}
class Dog extends Animal{
public void message() {
System.out.println("Dog");
}
}
class Bird extends Animal{
public void message() {
System.out.println("Bird");
}
}
public class TestExtends {
public static void func(Animal animal){
animal.message();
}
public static void main(String[] args) {
Dog dog=new Dog();
func(dog);
Bird bird=new Bird();
func(bird);
}
}
//运行结果:Dog
// Bird
通过这种引用,调用同一种方法,表现出不同形式,这种思想叫做多态。
③返回值
public static Animal func2(){
Dog dog=new Dog();
retun dog;
}
1.2 向下转型
上述代码可以改为:
public static void main(String[] args) {
Animal animal=new Dog("xiugou",10);
//animal.swimming();//编译错误
((Dog) animal).swimming();//正确,向下转型
}
但是,向下转型不安全
1.3 运行时绑定
这个过程叫做运行时绑定:
class Animal{
public String name="hahahah";
public int age;
public void message(){
System.out.println("Animal");
}
}
class Dog extends Animal{
@Override
public void message() {
System.out.println("Dog");
}
}
public class TestExtends {
public static void main(String[] args) {
Animal animal=new Dog();
animal.message();
}
}
//运行结果:Dog
A.对比子类和父类的message() 方法,我们发现:
- 函数名称相同
- 函数的参数列表相同(个数,类型)
- 函数返回值相同(也可不相同,但返回值之间要构成父子类关系,用的少)
我们将满足这三个条件的方式叫做:重写
B.发生运行时绑定的条件是:
1.先要向上转型 即父类的引用引用子类的对象
2.发生重写
注:程序编译的时候还是Animal的message方法,在运行时候绑定了Dog的message方法。
1.4 多态
父类引用 引用子类对象,通过父类引用调用父类和子类的同名覆盖方法。此时,如果父类引用 引用子类对象不一样,调用这个重写方法,表现的行为也是不一样的。
抽象类
1.1 抽象方法
- 抽象方法:使用abstract修饰方法,没有方法体,只有声明。定义的是一种规范,告诉子类必须要给抽象方法实现。
1.2 抽象类
-
抽象类不能使用new操作符创建他的实例
-
包含抽象方法的类,必须声明为抽象类
//抽象类 abstract class Shape{ public int size;//可以有普通成员属性 public Shape(){}//可以有构造方法 abstract public void draw();//抽象方法 }
-
抽象类的构造方法定义为protected,因为他只被子类使用,抽象类不能是private和final修饰的
-
一个普通类如果继承了抽象类,这个类需要重写这个抽象类当中的所有抽象方法。(如果这个子类不能实现所有的抽象方法,那么这个子类也必须定义为抽象的,且抽象方法是非静态的)
abstract class Shape{ abstract public void draw(); } abstract class Rect extends Shape{ abstract public void count(); } class Triangle extends Rect{ @Override public void draw(){} @Override public void count() {} }
- 这段代码中Rect继承了Shape,但是不能实现Shape所有的抽象方法,所以它定义为为abstract,而Triangle继承了Rect,所以Triangle要实现Rect和Shape所有抽象方法。
接口
1.1 interface
-
接口:只包含 常量和抽象方法
- 接口当中的方法,没有具体实现
- 接口当中的方法,默认全部都是public abstract
- 接口当中的成员变量,都是public static final
- 接口也是不能被实例化的(不能new)
-
接口的使用:implements
interface IShape{ public static final int num=10; //可以简写:int num=10; void draw(); //默认是public abstract,可省 } class Circle implements IShape{ @Override public void draw() { System.out.println("o"); } } public class TestInterfacs { public static void main(String[] args) { IShape iShape=new Circle(); iShape.draw(); } }
- Cirle也必须实现接口IShape里面的抽象方法。
- 继承只能继承一个,implements接口可以实现多个
interface IA{ } interface IB{ } abstract class ID{ } class IE extends ID implements IA,IB{ //继承必须在接口实现的前面,就是extends必须写在implements前面。 }
1.2 常用接口
-
Comparable
例题:给学生排序(如下方法排序有缺陷,因为将类写死了)
class Student implements Comparable<Student>{ public int age; public double scores; public String name; public Student(int age, double scores, String name) { this.age = age; this.scores = scores; this.name = name; } @Override public int compareTo(Student o) { //重写接口Comparable里面的方法 // if(this.age>o.age){ // return 1; // }else if (this.age==o.age){ // return 0; // }else{ // return -1; // } //根据年龄排序简化写法: // return o.age-this.age;//从大到小排序 // return this.age-o.age;//从小到大排序 // 根据姓名排序: return this.name.compareTo(o.name); //这是string里面的comperTo } } public class TestInterfacs2 { public static void main(String[] args) { Student s1=new Student(3,59,"zizi"); Student s2=new Student(15,69,"zizi"); int ret=s1.compareTo(s2); System.out.println(ret); } }
-
Comparator:比较器
//按照年龄排序 class AgeComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.age - o2.age; } } //按照分数排序 class ScoreComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { return (int)(o1.scores-o2.scores); } } //按照年龄排序 class NameComparator implements Comparator<Student>{ @Override public String compare(Student o1, Student o2) { return o1.compareTo(o2); } } public static class TestInterfacs2 { public static void main(String[] args) { Student[] students = new Student[2]; Student s1=new Student(3,59,"zizi"); Student s2=new Student(15,69,"zizi"); AgeComparator ageComp= new AgeComparator(); ScoreComparator scoreComp = new ScoreComparator(); NameComparator NameComp = new NameComparator(); Arrays.sort(students, scoreComp); System.out.println(Arrays.toString(students)); } } }
1.3 扩展
-
extends扩展:T3扩展到了T2和T1的功能
interface T1{} interface T2 extends T1{} interface T3 extends T2{}
1.4 Clonable接口
-
空接口,标志接口:代表如果一个类实现了这个接口,证明这个类就可以被clone
public interface Clonable{ }
-
class Money{ public double money=19.9; } class Person implements Cloneable{ public int age=99; public Money m=new Money(); @Override protected Object clone() throws CloneNotSupportedException{ return super.clone(); } @Override public String toString() { return "Person{" + "age=" + age + ", m=" + m + '}'; } } public class TestMoney { public static void main(String[] args) throws CloneNotSupportedException{ Person person=new Person(); System.out.println(person); Person person1=(Person) person.clone(); } }