java面向对象:面向对象的三大特征
面向对象的三大特征
1.封装
我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏)通常应用于禁止直接访问一个对象中数据的实际表示,而应用通过操作接口来访问,这称为信息隐藏。
记住这句话就够了:属性私有,get/set
get和set
public class Student {
//private属性私有
private String name;
private int age;
private char sex;
//get获取这个数据
public String getName() {
return name;
}
public int getAge() {
return age;
}
//set 给这个数据设置值
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
//idea快捷键:alt+insert
}
public class StudentDemo {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("刘德华"); //使用set设置值为刘德华
s1.setAge(50);
System.out.println(s1.getName()+"今年"+s1.getAge()+"岁了"); //刘德华今年50岁了
}
}
规范属性的合法化
如果这里age我们输入999
public class StudentDemo {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("刘德华"); //使用set设置值为刘德华
s1.setAge(999);
System.out.println(s1.getName()+"今年"+s1.getAge()+"岁了"); //刘德华今年999岁了
}
}
很明显没有人能活到999岁,所以这里我们必须做一些限制。
public class Student {
//private属性私有
private String name;
private int age;
private char sex;
//get获取这个数据
public String getName() {
return name;
}
public int getAge() {
return age;
}
//set 给这个数据设置值
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
//输入的年龄超过范围则显示0
if (age > 120 || age < 0 ){
this.age = 0;
} else {
this.age = age;
}
}
//快捷键:alt+insert
}
所以从某种意义上说,它可以规范属性的合法化。
2.继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extands的意思是“扩展”。子类是父类的扩展。
注意:JAVA中类只有单继承,没有多继承!
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。
- 子类继承父类,使用关键字extends来表示。
- 子类和父类之间,从意义上讲应该具有"is a"的关系
类继承
修饰符extends
//人
public class Person {
}
//学生也是人,所以他是Person子类
public class Student extends Person {
}
//老师也是人,所以他是Person子类
public class Teacher extends Person {
}
子类调用父类方法
//人
public class Person {
public void say(){
System.out.println("说话");
}
}
//学生
public class Student extends Person {
}
public class test {
public static void main(String[] args) {
Student student = new Student();
student.say(); //说话
}
}
//查询继承关系快捷键:Ctrl+H
子类集成父类,就会拥有父类的全部方法,之所以这样是因为我们所用的修饰符是public,同样的修饰符还有下面几个:
修饰符 | 意思 | 常用程度 |
---|---|---|
public | 公开的 | 重点最常用 |
protected | 受保护的 | |
default | 默认的 | |
private | 私有的 | 重点最常用 |
在java中所有的类默认直接或间接的集成了object类。
super的用法
这里的super要和this一起说,我们可以对比。
通过super调用父类public的属性
//父类,人
public class Person {
private String name ="kuangshen";
}
//人的子类,学生类
public class Student extends Person {
private String name = "qingjiang";
public void test(String name){
System.out.println(name); //对象传入的name
System.out.println(this.name); //当前类的name,结果为”qingjiang”
System.out.println(super.name); //报错,父类的属性或者方法是私有时super也是无法调用
}
}
当父类的属性或者方法是私有时super也是无法调用的。
super注意点
-
super调用父类的构造方法,必须在构造方法的第一行;
-
super必须只能出现在子类的方法或者构造方法中;
-
super和this不能同时调用构造方法,因为他们都需要放在第一行,所以不能同时!
super对比this
对比 | 代表的对象不同 | 前提 | 构造方法 |
---|---|---|---|
this | 本身调用者是对象 | 没有继承也可以使用 | 本类的构造 |
super | 代表父类对象的应用 | 只能在继承条件才可以使用 | 父类的构造 |
方法重写
静态方法中奇怪的现象
//父类
public class Person {
public static void run() {
System.out.println("人会跑步");
}
}
//子类
public class Teacher extends Person {
//重写父类中的run
public static void run(){
System.out.println("老师会跑步");
}
}
//测试类
public class Demo {
public static void main(String[] args) {
//老师类中已经重写了run方法
Teacher teacher =new Teacher();
teacher.run(); //老师会跑步
//父类的引用指向了子类,因为这和多态有关,我们先这么简单的理解。
Person person =new Teacher();
person.run(); //人会跑步
//等号右边newTeacher(),并且我们已经重写了run()方法,按照我们的思维结果应该是:老师会跑步。但是程序运行结果是:人会跑步。
//总结:方法的调用跟等号右边没什么关系,左边数据的定义是”人类”,所以会调用人类中的run。
}
}
方法的调用跟等号右边没什么关系,左边数据的定义是”人类”,所以会调用人类中的run。
非静态方法
现在我们把上面A和B类中的static去掉
//父类
public class B {
public void test(){
System.out.println("B=>test()");
}
}
//子类
public class A extends B {
@Override //重写修饰符
public void test(){
System.out.println("重写方法");
}
}
//演示
public class ceshi {
public static void main(String[] args) {
A a = new A();
a.test(); //A=>test()
B b = new A(); //子类重写了父类的方法
b.test(); //重写方法
}
}
注意:方法重写只跟非静态方法有关,和静态方法没有任何关系
3.多态
即同一方法可以根据发送对象的不同而采用多种不同的行为方式,一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
举例:一只猫
- 我们可以说猫是猫 cat=new 猫();
- 我们也可以说猫是动物animal=new 猫();
- 这里的猫在不同时刻表现出了不同的形态,这就是多态。
多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
注意:多态是方法的多态,属性没有多态性。
多态中成员访问特点
成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边
为什么成员变量和成员方法的访问不一样呢?因为成员方法有重写,而成员变量没有
package com.pokes001;
public class Person {
public void run() {
System.out.println("run");
}
}
package com.pokes001;
public class Student extends Person {
@Override
public void run(){
System.out.println("run");
}
public void eat(){
System.out.println("eat");
}
}
package com.pokes001;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//父类的引用指向子类
Student s1 = new Student(); //Student能调用自己的方法和继承父类的方法
Person s2 = new Student(); //父类型,可以指向子类,但是不能调用子类独有的方法
Object s3 = new Student(); //同上
s1.eat(); //子类重写了父类的方法,执行子类方法
//s2.eat();这个是直接报错,因为父类无法调用子类独有的方法
}
多态的好处和弊端
多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
多态的弊端:不能使用子类的特有功能
多态中的转型
向上转型
父类为Animal,有一个eat()方法,打印:动物吃东西
子类为Cat,有两个方法,其中一个是重写了父类的eat()方法,打印:猫吃鱼。另一个方法为playGame方法,打印:猫捉迷藏
public class AnimaDemo{
public static void main(String[] args){
//向上转型,等号左边是动物类Animal,右边是猫对象
Animal a = new Cat();
a.eat(); //猫吃鱼,调用了子类重写父类的方法
//可以直接调用父类Animal的eat方法和子类重写父类的eat方法,但是不能调用子类独有的方法playGame,否则会报错。
}
}
可以直接调用父类Animal的eat方法和子类重写父类的eat方法,但是不能调用子类独有的方法playGame,否则会报错。
向下转型
根据上面的例子我们是无法调用playGame方法,但是有时候必须要调用,这个时候我们需要将Animal a = new Cat()向下转型
public class AnimaDemo{
public static void main(String[] args){
Animal a = new Cat();
//向下转型
Cat c = (Cat)a; //可以这样理解:将动物类强制转为猫类,并赋值给c
c.eat(); //猫吃鱼
c.playGame() //猫捉迷藏
}
}
标签:java,name,16,子类,void,class,面向对象,父类,public
From: https://blog.csdn.net/annita2019/article/details/142953498