java面向对象
面向对象编程
面向过程 & 面向对象
- 面向过程思想
- 步骤清晰简单,第一部做什么,第二步做什么...
- 面向过程适合处理一些较为简单的问题。
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
什么是面向对象
- 面向对象编程(Object-Oriented Programming,OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的形式组织(封装)数据。
- 抽象
- 三大特征:
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
回顾方法及加深
-
方法的定义
- 修饰符
- 返回类型
- break和return的区别
- break:跳出switch,结束循环
- return:结束方法,返回一个结果!
- 方法名
- 参数列表
- 异常抛出
- 后面讲解
-
方法的调用
- 静态方法
- 非静态方法
- 形参和实参
- 值传递和引用传递
- this关键字
Demo01
package 方法的回顾及加深;
import java.io.IOException;
//回顾方法的定义
public class Demo01 {
//Demo01:类
//main:方法
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
public String sayHello(){
return "hello,world";
}
public void hello(){
return;
}
public int max (int a,int b){
return a>b ?a:b;//三元运算符
}
//抛出异常:
public void readFile(String file) throws IOException{
}
}
Demo02
package 方法的回顾及加深;
//回顾方法的调用
public class Demo02 {
public static void main(String[] args) {
//若要调用student中的say方法
//1.若say为静态方法,则可以通过类名和方法名直接调用。如下:
Student2.say();
//2.若say为非静态方法,无法直接调用,需要实例化这个类,用new。如下:
new Student2().speak();
//或
Student2 student2 = new Student2();
//对象类型 对象名 = 对象值
//3.然后可以用这个对象
student2.speak();
}
//若两个方法都是静态的或都是非静态的,则可以互相调用;若一个为静态一个为非静态,则不能互相调用。
public void a(){
b();
}
public void b(){
}
}
Demo03
package 方法的回顾及加深;
import javax.xml.ws.soap.Addressing;
//回顾型参与实参
public class Demo03 {
public static void main(String[] args) {
//形式参数和实际参数的类型要对应!
int add = new Demo03().add(1, 2);
System.out.println(add);
}
public int add(int a,int b){
return a+b;
}
}
Demo04
package 方法的回顾及加深;
//回顾方法的值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);//输出1
Demo04.change(a);
System.out.println(a);//输出1
}
//返回值为空
public static void change(int a){
a=10;
}
}
Demo05
package 方法的回顾及加深;
//回顾方法的引用传递
public class Demo05 {
//引用传递一般传递一个对象,但本质还是值传递
public static void main(String[] args) {
Person a = new Person();
System.out.println(a.name);//输出null
Demo05.change(a);
System.out.println(a.name);//输出hcss
}
public static void change(Person a){
//a是一个对象,指向的是---->Person a = new Person();这是一个具体的人,可以改变属性!
a.name ="hcss";
}
}
//一个类中只能有一个public class,但可以有多个class类。
//定义了一个Person类,有一个name属性。
class Person{
String name;//若不定义属性值,默认的应该是null。
}
定义的类:
package 方法的回顾及加深;
//一个学生类
public class Student2 {
//定义一个静态方法
public static void say(){
System.out.println("学生说话了!");
}
//定义一个非静态方法
public void speak(){
System.out.println("学生说话了!");
}
}
类与对象的关系
- 类是一种抽想的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
- 动物、植物、手机、电脑......
- Person类、Pet类、Car类,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为。
- 对象是抽想概念的具体实例
- 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。
类的调用:
1.实例化类语法:类名 对象名 = new 类型();
类名 对象名 = new 类型([实参列表]);
2.调用类中的属性:对象名.属性名
3.调用类中的方法:对象名.方法名([实参列表]);
构造方法:用于实例化类的对象的方法称为构造方法
有参构造方法:实例化对象的同时为类中的成员属性进行赋值
无参构造方法:实例化对象的时候对成员属性不进行赋值
语法格式:访问修饰符 方法名(){ //无参构造方法
}
访问修饰符 方法名([形参列表]){
this.成员属性 = 形参;
...........
}
创建与初始化对象
-
使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化以及 对类中构造器的调用。
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 1.必须和类的名字相同
- 2.必须没有返回类型,也不能写void
-
构造器必须要掌握
-
构造器的作用:1.实例化初始值。谁用new关键字时,本质是在调用构造器。
2.用来初始化对象的值。
-
注意点:一旦定义了有参构造,无参构造就必须显示定义。
-
快捷键Fn+Alt+Insert:生成构造器
-
this. = ,代表当前类,等号后一般为参数传进来的值。
- 可以调用成员属性:this.成员属性名
- 可以调用成员方法:this.成员方法名([参数列表]);
Demo01
package 创建与初始化对象;
public class Person {
/*
虽然什么都没写,但仍能在测试类中new处一个person方法
一个类什么都不写,它也会存在一个方法(构造器)。
构造器查看:打开项目中out中对应的方法的class文件。
*/
String name;
//手写一个显示的构造器
//构造器有一下两个特点:-1.必须和类的名字相同
//-2.必须没有返回类型,也不能写void
//无参构造:
public Person(){
}
/*
构造器的作用:1.实例化初始值。使用new关键字时,本质是在调用构造器。当new这个person时,程序会走构造器,就对name初始化了。
2.用来初始化对象的值
*/
//有参构造:
public Person(String a){
this.name = a;
}
//注意点:一旦定义了有参构造,无参构造就必须显示定义。
//快捷键Fn+Alt+Insert:生成构造器
}
//person的测试类:
/*
public static void main(String[] args) {
//使用new关键词实例化了一个对象
Person person = new Person("hcss");
System.out.println(person.name);//hcss
}
*/
Demo02
package 创建与初始化对象;
//学生类
public class Student1 {
//类中有一个个属性:字段。
String name;//默认值:null
int age;//默认值:0
//类中还有方法
public void study(){
System.out.println(this.name+"在学习");//this代表当前这个类,相当于这个学生在学习
}
}
/*
总结:类是一个抽象的模板,而通过new关键词可以创建不一样的具体的实例;
给模板赋值,就是各种不同的实例。
如:
person会有不同的属性;
person===>身高、体重、年龄、性别、国籍、民族
通过不同的属性组合来确定唯一的一个person。
*/
//student的测试类:
/*
public static void main(String[] args) {
//类:类是抽象的,若要引用类,则需要实例化出来
//通过new对类进行实例化。如:new Student();
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例!如下:
Student student = new Student();
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name = "小明";
xiaoming.age = 3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xh.name = "小红";
xh.age = 3;
System.out.println(xh.name);
System.out.println(xh.age);
}
*/
创建对象内存分析

Demo01
package 创建对象内存分析;
public class Pet {
//类中存在默认的无参构造
public String name;
public int age;
public void shout() {
System.out.println("叫了一声");
}
}
小结类与对象
1.类与对象
类是一个抽象的模板,对象是一个具体的实例
2.方法
方法的定义与调用
3.对象的引用
引用类型
基本类型(8个)
对象是通过引用来操作的:栈---->堆(引用就是指向对象的
一个地址)
4.对象的属性(字段)(成员变量)
默认初始化:
数字: 0 0.0
char: u0000
boolean: false
引用:null
定义:
修饰符 属性类型 属性名 = 属性值!
5.对象的创建和使用
-必须使用new 关键字创造对象,必须要有构造器
-对象的属性
Person hcss = new Person();
hcss.name
-对象的方法 hcss.sleep();
6.类
静态的属性 (属性)
动态的行为 (方法)
注意:
1.构造方法名和类型必须保持一致
2.没有访问者这一说法
3.如果在⼀个类中显示的定义了有参构造⽅法,则隐形⽆参构造将不存在。此时建议将 ⽆参构造⽅法显示定义
4.每个类都有构造⽅法,如果没有显示地为类定义构造⽅法,Java编译器将会为该类提供⼀个默认隐形 ⽆参构造⽅法
5.在创建⼀个类的对象时,⾄少要调⽤⼀个构造⽅法。
6.⼀个类中可以有多个构造⽅法,它们之间构成了重载,即构造方法重载。
封装
- 改露的露,该藏的藏
- 我们程序要追求”高内聚,低耦合“。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
- 封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 记住这句话就够了:属性私有,get/set
封装的意义:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 提高系统的可维护性
Demo01
package 封装;
//类
public class Student {
//封装大部分用于属性
//private:私有
//属性私有:
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//年龄
//提供一些可以操作这个属性的方法!
//提供一些public的get、set的方法
//get:获得这个数据
public String getName(){
return this.name;
}
//set:给这个数据设置值
public void setName(String a){
this.name = a;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120 ||age<0){
this.age=3;
}else {
this.age = age;
}
//若数值不合法,可在set中进行设置
//快捷键:鼠标右键选择点击生成,选择get/set生成。
}
}
//Student的测试类:
/*
public static void main(String[] args) {
Student s1 = new Student();
String name = s1.getName();
s1.setName("hcss");
System.out.println(s1.getName());
int age = s1.getAge();
s1.setAge(1);//不合法的
System.out.println(s1.getAge());
}
*/
继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
-
extends的意思是”扩展“。子类是父类的扩展。
-
java中类只有单继承,没有多继承!
-
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
-
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
-
子类和父类之间,从意义上讲应该具有”is a“的关系。
-
object类
-
super
-
方法重写
-
super注意点:
-
super调用父类的构造方法,必须在构造方法的第一个
-
super必须只能出现在子类的方法或者构造方法中
-
super 和 this 不能同时调用构造方法!
-
对比this:
-
两者代表的对象不同:this代表本身调用者这个对象;super代表父类对象的引用。
-
使用前提不一致:this没有继承也可以使用;super只能在继承条件下(有继承关系时)才可以使用 。
-
调用构造方法不同:
this();调用本类的构造
super();调用父类的构造
-
-
-
重写:需要有继承关系,子类重写父类的方法!
-
方法名必须相同
-
参数列表必须相同
-
修饰符:范围可以扩大:public > Protected > Default > private
-
抛出的异常:范围可以被缩小,但不能扩大
ClassNotFoundException --> Exception(大)
-
重写,子类的方法和父类必须要一致;方法体不同!
-
-
为什么要重写:
- 父类的功能,子类不一定需要,或者不一定满足!
-
快捷键:鼠标右键选择点击生成,选择Override
Demo01_Student
package 继承;
//Student(子类/派生类) is 人
public class Student extends Person{ //extends:继承Person类
//Student想用Person类除了继承,还有组合的方法。如下:
//Person person;
//子类继承了父类,就会拥有父类的全部方法!
//快捷键Ctrl+H:打开继承结构。
/*===============================================================
=================================================================
=================================================================
=================================================================
*/
//super:
//怎样在子类(student)中访问父类(person)的属性呢? 用super访问。
private String name = "pqy";
public void test (String name){
System.out.println(name);//花朝十三
System.out.println(this.name);//pqy
System.out.println(super.name);//hcss
}
/*==================================================*/
public void print(){
System.out.println("Student");
}
public void test1 (String name){
print();//Student
this.print();
super.print();//Person
}
/*===============================================================
=================================================================
=================================================================
=================================================================
*/
public Student() {
System.out.println("Student(子类)的无参构造执行了");
}
/*
父类的无参构造先执行,其次执行子类的无参构造。
所以有一句隐藏代码:super(),默认子类调用了父类的无参构造,super()。
调用父类的构造器,必须要在子类构造器的第一行。
*/
}
//测试类:
/*
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
System.out.println("======================");
//在java中,所有的类都默认直接或者间接继承object类
Person person = new Person();
//若类中没有任何方法,在调用类时,仍然有很多没有定义过的方法可以使用
//因为有一个隐藏的类在object类下。而在Java中,所有的类都默认直接或者间接继承object类
//如:
person.hashCode();
person.toString();
person.notify();
}
*/
//super测试类:
/*
*/
Demo02_Teacher
package 继承;
//Teacher(子类/派生类) is 人
public class Teacher extends Person{
}
Demo03_Person
package 继承;
//Person类 人:父类
public class Person {
//子类可以继承父类的所有方法
//修饰符:
//public
//private
//default(默认的)
//protected(受保护的)
public int money = 10_0000_0000;
public void say() {
System.out.println("说了一句话。");
}
/*===============================================================
=================================================================
=================================================================
=================================================================
*/
//super:
protected String name = "hcss";
public void print() {
System.out.println("Person");
}
/*若修饰符变为私有的private,则不能被调用,
因为私有的东西无法被继承。
*/
/*===============================================================
=================================================================
=================================================================
=================================================================
*/
//一个无参构造器:
public Person() {
System.out.println("Person(父类)无参执行了");
}
}
//测试类:
/*
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
System.out.println("======================");
//在java中,所有的类都默认直接或者间接继承object类
Person person = new Person();
//若类中没有任何方法,在调用类时,仍然有很多没有定义过的方法可以使用
//因为有一个隐藏的类在object类下。而在Java中,所有的类都默认直接或者间接继承object类
//如:
person.hashCode();
person.toString();
person.notify();
}
*/
//super测试类:
/*
*/
Demo04_继承-方法重写
package 继承_方法重写;
public class A extends B {
//Override 重写
@Override //注解:有功能的注释!
public void test() {
System.out.println("A=>test()");
}
}
//测试类:
/*
public static void main(String[] args) {
//静态方法和非静态方法区别很大
//当方法为静态方法时,方法的调用只和等号左边,即定义的数据类型有关。
//当为非静态方法时,则重写。
A a = new A();
a.test();//程序走A类中的方法
//父类的引用指向了子类
B b = new A();//子类重写了父类的方法
b.test();//程序走B类中的方法
//重写只和非静态方法有关。
//重写的关键词只能是public,不能是私有的。
}
*/
Demo05_继承-方法重写
package 继承_方法重写;
//重写都是方法的重写,和属性无关。
public class B {
public void test(){
System.out.println("B=>test()");
}
}
//测试类:
/*
public static void main(String[] args) {
//静态方法和非静态方法区别很大
//当方法为静态方法时,方法的调用只和等号左边,即定义的数据类型有关。
//当为非静态方法时,则重写。
A a = new A();
a.test();//程序走A类中的方法
//父类的引用指向了子类
B b = new A();//子类重写了父类的方法
b.test();//程序走B类中的方法
//重写只和非静态方法有关。
//重写的关键词只能是public,不能是私有的。
}
*/
多态
-
即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
-
多态存在的条件
- 有继承关系
- 子类重写父类
- 父类的引用指向子类对象
-
注意:多态是方法的多态,属性没有多态性。
-
instanceof,(类型转换)引用类型
- 作用:判断一个对象是什么类型
-
多态注意事项:
-
多态是方法的多态,属性没有多态
-
父类和子类有关系,才能进行转换;若强转则会出现转换异常:ClassCastException!
-
多态存在的条件:3.1继承关系;
3.2方法需要重写;(若子类和父类存在同一种方法,在调用方法时,执行子类的方法。)
3.3父类引用指向子类对象!Father f1= new Son();
-
-
不能被重写的方法:
- static是静态方法,属于类,它不属于实例。
- final是常量的,无法改变
- private是私有方法,不能重写。
-
- 1.父类的引用指向子类的对象
- 2.如果把子类转换为父类,是向上转型,不用强制转换
- 3.如果把父类转换为子类,是向下转型,需要强制转换
- 4.方便方法的调用,减少重复的代码!更简洁
抽象:封装、继承、多态
Demo01
package 多态;
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
//测试类:
/*
//一个项目应该只存在一个main方法,作为总的测试类
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//但可以指向的引用类型就不确定了:父类的引用指向子类。
//Student能调用的方法都是自己的或者继承父类的!
Student s1 = new Student();
//Person是父类型,可以指向子类,但是不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
((Student)s2).eat();//子类重写了父类的方法,执行了子类的方法
s1.run();
}
*/
Demo02
package 多态;
public class Person {
public void run(){
System.out.println("run");
}
}
//测试类:
/*
//一个项目应该只存在一个main方法,作为总的测试类
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//但可以指向的引用类型就不确定了:父类的引用指向子类。
//Student能调用的方法都是自己的或者继承父类的!
Student s1 = new Student();
//Person是父类型,可以指向子类,但是不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
((Student)s2).eat();//子类重写了父类的方法,执行了子类的方法
s1.run();
}
*/
Dome03_instanceof
package 多态_instanceof;
public class Person {
public void ren(){
System.out.println("run");
}
}
//测试类:
/*
public static void main(String[] args) {
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
//样式:System.out.println( X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。
System.out.println("============================================");
System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
System.out.println(object instanceof Person);//ture
System.out.println(object instanceof Object);//ture
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("========================================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//ture
System.out.println(person instanceof Object);//ture
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译报错!
System.out.println("========================================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//ture
System.out.println(student instanceof Object);//ture
//System.out.println(student instanceof Teacher);//编译报错!
//System.out.println(student instanceof String);//编译报错!
}
*/
//转换测试类:
/*
public static void main(String[] args) {
//类型之间的转换: 父类高子类低
//Object > String
//Object > Person > Teacher
//Object > Person > Student
//Student obj = new Student();
//Student类能够直接转为Person类,如下: 因为Person类是高的一方,Student是低的一方,能够直接转换。
//高 低
Person obj = new Student();
Student student = (Student) obj;
( (Student) obj).go();
//子类转换为父类,可能会丢失自己的本来的一些方法!
Student student1 = new Student();
student.go();
Person person = student;
}
*/
Dome04_instanceof
package 多态_instanceof;
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
//测试类:
/*
public static void main(String[] args) {
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
//样式:System.out.println( X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。
System.out.println("============================================");
System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
System.out.println(object instanceof Person);//ture
System.out.println(object instanceof Object);//ture
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("========================================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//ture
System.out.println(person instanceof Object);//ture
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译报错!
System.out.println("========================================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//ture
System.out.println(student instanceof Object);//ture
//System.out.println(student instanceof Teacher);//编译报错!
//System.out.println(student instanceof String);//编译报错!
}
*/
//转换测试类:
/*
public static void main(String[] args) {
//类型之间的转换: 父类高子类低
//Object > String
//Object > Person > Teacher
//Object > Person > Student
//Student obj = new Student();
//Student类能够直接转为Person类,如下: 因为Person类是高的一方,Student是低的一方,能够直接转换。
//高 低
Person obj = new Student();
Student student = (Student) obj;
( (Student) obj).go();
//子类转换为父类,可能会丢失自己的本来的一些方法!
Student student1 = new Student();
student.go();
Person person = student;
}
*/
Demo05_instanceof
package 多态_instanceof;
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
//测试类:
/*
public static void main(String[] args) {
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
//样式:System.out.println( X instanceof Y);//能不能编译通过;若X与Y之间有父子关系,则编译通过;X指向的类型是Y的子类型或与Y有关,则通过。
System.out.println("============================================");
System.out.println(object instanceof Student);//ture//通过instanceof判断当前对象object是否是Student类型的。
System.out.println(object instanceof Person);//ture
System.out.println(object instanceof Object);//ture
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("========================================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//ture
System.out.println(person instanceof Object);//ture
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译报错!
System.out.println("========================================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//ture
System.out.println(student instanceof Object);//ture
//System.out.println(student instanceof Teacher);//编译报错!
//System.out.println(student instanceof String);//编译报错!
}
*/
//转换测试类:
/*
public static void main(String[] args) {
//类型之间的转换: 父类高子类低
//Object > String
//Object > Person > Teacher
//Object > Person > Student
//Student obj = new Student();
//Student类能够直接转为Person类,如下: 因为Person类是高的一方,Student是低的一方,能够直接转换。
//高 低
Person obj = new Student();
Student student = (Student) obj;
( (Student) obj).go();
//子类转换为父类,可能会丢失自己的本来的一些方法!
Student student1 = new Student();
student.go();
Person person = student;
}
*/
抽象类
-
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
-
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
-
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
-
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
-
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
抽象类的特点:
1.不能new这个抽象类,只能靠子类去实现它,是一个约束。
2.抽象类中可以写普通的方法
3.抽象方法必须在抽象类中
4.存在的意义:提高开发效率
Demo01
package 抽象类;
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类也为抽象类
public class A extends Action{
@Override
public void dosomething() {
}
}
Demo02
package 抽象类;
//在一个类中使用abstract,那就变成了一个抽象类。
public abstract class Action {
//在一个方法中使用abstract,就是抽象方法;只有方法的名字,没有方法的实现。
public abstract void dosomething();
//抽象类的本质还是类,类是需要用rxtends继承的,但extends是单继承,在java中,接口可以多继承。
}
接口
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有
-
接口:只有规范!自己无法写方法,是专业的约束,主要是约束和实现分离。
-
如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。
-
定义格式:
interface 接口名称{ 全局常量; 抽象方法; }
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是....则必须能....的思想。
- 接口的本质是契约,就像法律一样。制定好大家都遵守。
- OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计 模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。
接口的作用:
1.约束
2.定义一些方法,让不同的人实现
3.接口中默认的方法是public abstract
4.接口中常量的默认是public static final
5.接口不能直接被实例化,因为接口中没有构造方法
6.可以通过implements实现多个接口
7.要实现接口必须重写里面的方法
Demo01
package 接口;
public interface TimeService {
void timer();
}
Demo02
package 接口;
//interface:接口
public interface UserService {
//接口中的所有定义的方法其实都是抽象的,默认为public abstract
public abstract void add(String name);
void delete(String name);
void update(String name);
void query(String name);
//接口都需要有实现类。
//接口中的所有定义的属性其实都是常量,默认为public static final
public static final int AGE = 99;
}
Demo03
package 接口;
//类可以通过implements实现接口
//实现了接口的类,就需要重写接口的方法
//这样就从侧面利用接口实现了多继承
public class UserServiceUmpl implements UserService,TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
内部类
-
内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
-
1.成员内部类
-
2.静态内部类
-
3.局部内部类
-
4.匿名内部类
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。 不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。
如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
Demo01
package 内部类;
import com.sun.xml.internal.bind.v2.model.core.ID;
import javax.sound.midi.Soundbank;
public class Outer {
//成员内部类:
private int id = 10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//内部类直接访问外部类的一些东西,获得外部类的一些私有属性
public void getID(){
System.out.println(id);
System.out.println("============================================");
}
}
//局部内部类:
public void method(){
class Inner{
public void in(){
}
}
}
}
//Outer测试类
/*
public static void main(String[] args) {
//通过new实现外部类的调用
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
*/
Demo02
package 内部类;
public class Test {
//匿名内部类:
public static void main(String[] args) {
//有名字的初始化类
Apple apple = new Apple();
//没有名字的初始化类,不用将实例保存到变量中
new Apple().eat();
new UserService(){
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
浙公网安备 33010602011771号