Java 学习笔记--面向对象的三大特征
面向对象的三大特征
封装
封装 将类的某些信息隐藏在类的内部 不允许外部程序直接访问 只能通过该类提供的方法来实现
封装的好处 只能通过规定方法访问 隐藏类的实现细节 方便修改 方便加入控制语句
具体实现
属性用private修饰
方法用public修饰
public class Person {private String name;public void setName(String name){ this.name=name; } public String getName(){ return name; }}/** 利用构造方法隐藏信息* */private String name; private int age; public Person(String name,int age){ this.name=name;
this关键字
代表自身类的对象
使用this关键字引用成员变量
使用this关键字引用成员方法
必须放在非静态方法中
private String name;public void setName(String name){ this.name=name; }
常常用来区分成员变量和局部变量
继承
继承是从已有类中派生出新的类 新的类能够继承已有类的属性方法 并扩展新的能力
继承实现代码可重用的根基,是提高代码可扩展性的主要途径。
在Java中使用extends表示继承
不支持多继承 一个类只能有一个直接父类
继承后的子类可以调用父类所有的非私有属性和非私有方法
访问形式
[访问权限修饰符 ] [修饰符] 子类名 extends 父类名{子类体}
public class Animal {/** 父类* */ private String name; private int age;public Animal(){ super(); System.out.println("这是动物的构造方法");} 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 class Dog extends Animal{/** 子类继承父类* */ private String kind;public Dog(){ super(); System.out.println("这是狗的构造方法");} public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } public void voice(){ System.out.println("wangwang"); }}
继承中的传递性
C类从B类继承,B类又从A类继承
那么C类就具有B类和A类的所有非私有属性和非私有方法
当一个没有继承任何一个类时,Jvm会默认让类继承Object类
Object是 Java为所有类提供的基类
继承中的构造方法
子类构造方法总是先调用父类构造方法,默认情况下,调用父类无参构造方法
可以在子类构造方法的第一行,使用super关键字调用父类任意一个构造方法
如果用super,必须写在构造方法的第一句
如果子类的构造方法中没有显式地调用基类构造方法,则系统默认调用基类无参数的构造方法。
super关键字用途
super关键字代表父类的引用,在程序中主要的用途
在子类构造方法中要调用父类的构造方法,需要注意:super语句只能出现在子类构造方法体的第一行。
用“super.成员变量名”来引用父类成员变量
用“super.方法名(参数列表)”的方式访问父类的方法。
与this的区别,this通常指代当前对象,super通常指代父类。
原因:
public class XiaoTianQuan extends Dog{/** 在创建子类对象时 会同时创建父类的对象* 在调用子类的构造方法时,会同时调用父类的构造方法* */ public XiaoTianQuan(){ super();//默认调用构造方法 默认调用父类中无参的构造方法 //如果显示调用必须放在构造方法的第一行 super.name(); System.out.println("这是哮天犬的构造方法");}}
方法的重写
当子类中的实现功能不能满足父类时
父类功能不能满足子类的功能 需要重写子类的方法
重写时 父类类型必须与子类类型一致 返回值 参数 访问权限父类必须大于子类
/*父类中的声音方法*/public void voice(){ System.out.println("wangwang"); }/*重写子类中的声音方法*/ublic void voice(){ System.out.println("我是哮天犬 我不叫"); }
类之间的关系
关联关系 是指B类对象作为A类的属性存在
分类 单向连接 A类关联B类
双向连接 A类关联B类,B类关联A类
public class Person { private Mobile num; //一对一关联 单向关联 private Mobile[] num1;//一对多关联 集合 数组} //Mobile作为Person的属性存在public class Mobile { String num; private Person ren1;//双向关联 public String getNum() { return num; } public void setNum(String num) { this.num = num; }}
依赖关系 A类使用到了另一个类B,B对象作为A类的方法参数存在
public class Person { public void feed(Dog dog){ //Dog类作为Person类的方法参数存在 //这个方法可以调用Dog类 dog.setName("肉肉"); System.out.println(dog.getName());}}
抽象类
抽象类 作为定义 让其他类继承 一个类继承抽象类 要么将子类声明为抽象类 要么重写抽象类中的所有抽象方法
抽象方法 被abstract修饰 ,没有具体的信息 ,没有方法体
**有抽象方法的必定是抽象类 **
在顶层类中方法的实现与子类大多数不相同 在顶层类中可以将方法声明为抽象方法
public abstract class Animal {//定义一个动物类/*抽象方法必须写在抽象类中*/ public abstract void eat(); public abstract void name();}
public class Dog extends Animal {//Dog类继承了动物类 @Override public void eat() {//重写了eat方法 System.out.println("优雅的吃"); } @Override public void name() { //重写name方法 System.out.println("我是铛铛"); }}
抽象类不能实例化对象 但成员变量 成员方法 构造方法依然存在
抽象类不能被实例化(创建对象) 但可以有构造函数
接口
interface 定义接口
接口的特性
接口是隐式抽象的 不用abstract关键字
接口不能被实例化
实现类必须重写接口中的所有方法 否则,类必须声明为抽象的类
实现类可以实现多个接口
接口中的变量都是静态常量
public interface Animal extends Animal2 {/*一个接口也可以继承多的接口*/ public static final int num=10; void eat(); void sleep(); /* interface 定义接口 * public static final默认修饰 * 接口中所定义的方法为抽象方法 * 所定义的均为常量 * */}
public interface Animal2 {//接口2 被Animal 继承 void play();}
public class Cat implements Animal, Animal2 {/*一个类可以实现多个接口实现接口的时 必须重写接口中的方法 否则,类必须声明为抽象的类*/ /* * 一个接口可以被多个类实现 * * */ @Override public void eat() { } @Override public void sleep() { } @Override public void play() { } public void ctachMouse(){ System.out.println("我抓老鼠"); }}
多态
同一种事物,在不同时刻表现不同的状态
存在的三个必要有条件:
要有继承 (包括接口的实现)
要有重写
父类引用指向子类对象
public abstract class Animal { int num=10; abstract void eat(); abstract void sleep(); abstract void play();public static void character(){ System.out.println("我们很漂亮");}}
public class Dog extends Animal{ public static void character(){ System.out.println("test的我们很漂亮"); } @Override public void eat() { System.out.println("铛铛在吃"); } @Override public void sleep() { System.out.println("铛铛在睡觉"); } @Override public void play() { System.out.println("铛铛在玩"); }}
public class Cat extends Animal{ @Override public void eat() { System.out.println("小猫在吃鱼"); } @Override public void sleep() { System.out.println("小猫在睡觉"); } @Override public void play() { System.out.println("小猫在玩耍"); }}
public class Test { /*多态*/ public static void main(String[] args) { Animal dog=new Dog(); Animal cat=new Cat(); /* * 向上转型 --父类类型表示所有的子类 为父类类型 不能使用子类中特有的方法 提高程序的扩展性。 * */ Test t1=new Test(); /*成员方法 * 左边编译 右边运行 执行的为右边 * * */ t1.eat(dog); t1.eat(cat); /*调用静态方法时 调用的是Animal类的静态方法 *编译和运行都是Animal * */ Animal animal=new Dog(); animal.character(); /*常量 * 编译和运行都是Animal * */ System.out.println(animal.num); }/*调用Animal接口*/ /** 多态应用 同一种事务,在不同时刻表现不同的状态* */ public void eat(Animal animal){ /* * 向下转型 有父类转型为子类类型 为了使用子类中的特有方法。 * */ if (animal instanceof Dog){//在运行时检测判断animal中实际包含是否指定的类型 Dog dog=(Dog)animal; dog.sleep(); } /* * * */ animal.eat(); }}
final关键字
final可以修饰类 属性 方法
定义在属性中:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改。
定义在方法中:子类里不可被覆盖。
定义在类中:不能被定义为抽象类或是接口,不可被继承。
public class ParcticeFinal { /* * final可以修饰类 常量 方法 * 被final修饰 的类不能被继承 * */ static final int num=10;//final修饰的必须为常量 一般情况会在前面加上 static final int sum;//必须要构造方法 public ParcticeFinal(int sum){ this.sum=sum; } public final void Test(){ /*final修饰的方法不能被重写 * * */ } public static void main(String[] args) { ParcticeFinal t1=new ParcticeFinal(5); //如果构造方法改变必须 传进sum值 t1.Test(); }}