面向对象总结"/>
java 面向对象总结
目录
一.什么是类?什么是对象?如何创建类 如何创建对象?类中可以包含什么?类与对象之间的关系?
二.方法
三 变量
四 继承 -----代码复用
五 关键字
六 接口
七 多态
一.什么是类?什么是对象?如何创建类 如何创建对象?类中可以包含什么?类与对象之间的关系?
类:从字面上看 是类型/类别之意,代表一个类的个体,是一种数据类型(引用数据类型)
对象:对象是类的具体实例,
如何创建类:类由关键字class修饰其基本的结构如下代码中,
对象 :软件中真实存在的单个个体/东⻄;对象由关键字 new 修饰
类中可以包含:
描述对象的属性-----成员变量
描述对象的行为/功能和动作的----------方法
public class Student{//创建学生对象
String name ;//成员变量 name
int age;/成员变量 agevoid study(){//方法 studySystem.out.println(name+"在学习...");
}}
类与对象之间:类是对象的模板,对象是类的具体的实例;简言之、一个类可以创建多个对象
分类:主要分为成员内部类和匿名内部类
成员内部类
定义:类中套类,外面的称为外部类,里面的称为内部类
范围:内部类通常只服务于外部类,对外不具备可见性
内部类对象需要在外部类中创建
内部类中可以直接访问外部类的成员(包括私有的),
补充:内部类中有个隐式的引用指向了创建它的外部类对象:外部类名.this-----API用
隐式方式:
this:指代当前对象
super:指代当前对象的超类对象
外部类名.this:指代当前对象的外部类对象
案例
public class InnerClassDemo {public static void main(String[] args) {Mama m = new Mama();//Baby b = new Baby(); //编译错误,内部类对外不具备可见性}
}class Mama { //外部类private String name;void create(){Baby b = new Baby(); //正确,内部类对象通常在外部类中创建}class Baby{ //内部类void showName(){System.out.println(name);//Mama.this指代当前对象的外部类对象System.out.println(Mama.this.name);//System.out.println(this.name); //编译错误,this指代当前Baby对象}}
}
匿名内部类:---------大大简化代码
何时用:若想创建一个类(派生类)的对象,并且对象只创建一次,可以设计为匿名内部类
名内部类中不能修改外面局部变量的值,因为该变量在此处会默认为final的-----API用
案例
public class NstInnerClassDemo {public static void main(String[] args) {//1)创建了Aoo的一个派生类,但是没有名字//2)为该派生类创建了一个对象,名为o1// ---new Aoo(){}是在创建派生类对象,而后向上造型为Aoo类型//3)大括号中的为派生类的类体Aoo o1 = new Aoo(){};//1)创建了Aoo的一个派生类,但是没有名字//2)为该派生类创建了一个对象,名为o2//3)大括号中的为派生类的类体Aoo o2 = new Aoo(){};int num = 5;num = 55; //正确//1)创建了Boo的一个派生类,但是没有名字//2)为该派生类创建了一个对象,名为o3//3)大括号中的为派生类的类体Boo o3 = new Boo(){void show(){System.out.println("showshow");//num = 88; //编译错误,在此处num会默认为final的}};o3.show();}
}abstract class Boo{abstract void show();
}abstract class Aoo{
}
二.方法
1 组成:由返回值类型+方法签名(方法名+参数列表)组成
2 方法的重载:
作用:方便用户调用
组成:
发生在同一类中,方法名相同 ,参数列表不同;
编译器在编译过程中,会根据方法签名自动绑定方法。
调用:调用方法如下:
//演示⽅法的重载
class Aoo{void show(){}void show(String name){}void show(int age){}//int show(){ return 1; } //编译错误,重载与返回值类型⽆关//void show(String address){} //编译错误,重载与参数名称⽆关
}
//演示重载⽅法的调⽤
public class OverloadDemo {
public static void main(String[] args) {Aoo o = new Aoo();o.show();o.show("zhangsan");o.show(25);}
}
3.构造方法又称构造器、构造函数、构建器:
组成:与类同名,没有返回值类型(连void都没有)
作用:给成员变量赋初值;
调用:在创建(new)对象时自动调用;
创建:
//构造方法的创建
Student(String name,int age,String address){this.name = name; //zs.name="zhangsan"this.age = age; //zs.age=25this.address = address; //zs.address="LF"}
注意要点:
若自己没有写构造方法,系统会默认调用无参构造方法,
若自己写了构造方法,系统将不再默认提供,在调用时,需自己调用;
构造方法也可以重载
3.方法重写
组成:发生在父子类中,方法名相同,参数列表相同
作用:重写 ,覆盖 ,完善父类中不完整的行为;
调用:重写方法被调用时,看调用的对象类型,一般情况下,new的对象是什么,那么,就只能调用什么且遵守两同两小一大的规则;
规则:
两同:方法名相同、参数列表相同
两小:派生类的方法的返回值类型小于等于超类的;注:(当类型为void和基本类型时。返回值的类型必须相同,当类型为引用类型时,返回值的类型必须可以小于或等于该类型)
派生类方法抛出异常的权限小于等于超类的
一大: 派生类方法的访问权限大于等于超类的
案例:
class Person{String name;int age;String address;Person(String name,int age,String address){this.name = name;this.age = age;this.address = address;}void sayHi(){System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address);}
}
class Student extends Person{String stuId; //学号Student(String name,int age,String address,String stuId){super(name,age,address);this.stuId = stuId;}void sayHi(){System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address+",学号为"+stuId);}
}
class Teacher extends Person{double salary; //工资Teacher(String name,int age,String address,double salary){super(name,age,address);this.salary = salary;}void sayHi(){System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address+",工资为"+salary);}
}public class Test {public static void main(String[] args) {//将学生/老师/医生统一装到Person数组中,只需要一个for即可//向上造型的好处----实现了代码复用,后期扩展、维护也相当方便Person[] ps = new Person[7];ps[0] = new Student("zhangsan",25,"LF","111"); //向上造型ps[1] = new Student("lisi",24,"JMS","222");ps[2] = new Student("wangwu",26,"SD","333");ps[3] = new Teacher("zhaoliu",36,"SX",20000.0);ps[4] = new Teacher("sunqi",45,"LF",30000.0);ps[5] = new Doctor("qinba",46,"JMS","主任医师");ps[6] = new Doctor("gaojiu",35,"SD","主治医师");for(int i=0;i<ps.length;i++){ //遍历所有人ps[i].sayHi(); //每个人都跟大家问好}//能点出什么来,和,到底调用的是哪个-----一定要分开看//重写方法被调用时,看对象的类型Student z = new Student("zhangsan",25,"LF","111");Person p = new Student("zhangsan",25,"LF","111");z.sayHi(); //调用Student类的sayHi()p.sayHi(); //调用Student类的sayHi()}
}
4 抽象方法
由abstract修饰 只有方法的定义,没有具体的实现(连{}都没有)
例如:public abstract void sayHi();
抽象方法存在的意义:保证当发生向上造型时,通过超类的引用能点出来那个方法
三 变量
变量主要包含了 成员变量、局部变量、基本类型变量、引用类型变量
1 局部变量:在方法中的变量
2 基本类型变量:基本类型变量中存放的是具体的数,一般存放于栈中
3.引用类型变量:引用类型变量中存放的是是堆中对象的地址
注意:给引用类型数组的元素赋值时,必须得new对象
若想访问对象的数据/调用方法,需要通过数组元素去打点
4 成员变量:在类中 ,方法在外的变量,且根据有无修饰词static 来修饰,分为实例变量和静态变量;
实例变量:没有static修饰,一般属于对象,一般情况下存储于堆中、且实例变量的多少根据所new的对象来决定,一般有多少对象就有多少实例变量
如何访问:通过引用名/对象打点访问
静态变量:由static修饰;一般属于类、存储于方法区中,且静态变量不会随着所new对象的数目增加,一般只在方法区中出现一次
如何访问:通过类名打点访问
何时用:所有对象所共享的数据(图片、音频、视频等)
静态变量案例:
class Loo{int a; //实例变量static int b; //静态变量Loo(){a++;b++;}void show(){System.out.println("a="+a+",b="+b);}
}public class StaticDemo {public static void main(String[] args) {Loo o1 = new Loo();o1.show();Loo o2 = new Loo();o2.show();Loo o3 = new Loo();o3.show();System.out.println(Loo.b); //常常通过类名点来访问}
}
四 继承 -----代码复用
如何继承:通过extends来实现类的继承
1 在类中如何继承:java规定 ,继承是发生在超类/父类、派生类/子类之间,不能发生在同一类中。其 特点为具有传递性:
父类/超类:
父类/超类中一般是共有的属性和方法 / 封装共有的属性和行为
一个超类可以有多个派生类,但一个派生类只能继承一个超类-----单一继承
为所有派生类提供统一的类型---------向上造型
派生类/子类:
派生类/子类中是给对象所拥有的特殊属性和方法
访问范围:派生类的+超类的或派生类,而超类不能访问派生类
注意:构造派生类之前必须先构造超类
在派生类构造方法中若没有调用超类构造方法,则默认super()调超类无参构造方法
在派生类构造方法中若自己调用了超类构造方法,则不再默认提供
super()调用超类构造方法,必须位于派生类构造方法的第一行
继承要符合is(是)的关系
案例:
public class SuperDemo {public static void main(String[] args) {Boo o = new Boo();}
}class Aoo{Aoo(){System.out.println("超类构造...");}
}
class Boo extends Aoo{Boo(){//super(); //默认的,写不写都在System.out.println("派生类构造...");}
}class Coo{Coo(int a){}
}
class Doo extends Coo{Doo(){super(5); //调用超类的有参构造}/*//如下代码为默认的Doo(){super(); //超类若没有无参构造,则编译错误}*/
}
2 向上造型
定义:超类型的引用指向派生类的对象
调用:能点出来什么,看引用的类型-------------这是规定
规则:前面是超类型 后面是派生类型
案例:
package ooday04;
//向上造型的演示
public class UploadDemo {public static void main(String[] args) {Aoo o1 = new Aoo();o1.a = 1;o1.show();//o1.b = 2; //编译错误,超类不能访问派生类的//o1.test(); //编译错误Boo o2 = new Boo();o2.b = 1;o2.test();o2.a = 2; //正确,派生类可以访问超类的o2.show(); //正确Aoo o3 = new Boo(); //向上造型o3.a = 1;o3.show();//o3.b = 2; //编译错误,能点出来什么,看引用的类型//o3.test(); //编译错误}
}class Aoo{int a;void show(){}
}
class Boo extends Aoo{int b;void test(){}
}
五 关键字
常见关键字:package、import、final、static、this、super、static final、abstract、public、protected、默认、private,其中public、protected、默认、private,为访问控制修饰符;其目的是保护数据的安全性。
1.package(包)
作用:避免类名冲突
规则:同一包下,类名不能重名,不同包下,类名可以重复
2.import(导入):
作用:同一包中的类 可以直接访问,但是不同中的类,是不可以访问的,若想挎包访问,需加上该类所处的包名 如下案例代码:
package ooday04_1;
import ooday01.Student;
3.final(最终的 不可改变的)
基本规则:
修饰变量:变量不能被改变
修饰方法:方法不能被重写
修饰类:类不能被继承
4.static 静态的
由 static修饰的方法称为静态方法,静态方法属于类,存储在方法区中,只有一份
静态方法的调用:
- 常常通过类名点来访问
- 静态方法中没有隐式this传递,所以不能直接访问实例成员,只能直接访问静态成员
何时用:方法的操作与对象无关(不需要操作对象的数据)
案例:
class Moo{int a; //实例变量(对象点来访问)static int b; //静态变量(类名点来访问)void show(){ //有隐式thisSystem.out.println(this.a);System.out.println(Moo.b);}static void test(){ //没有隐式this//静态方法没有隐式this传递//没有this就意味着没有对象//而实例变量a必须由对象点来访问//所以如下语句发生编译错误//System.out.println(a); //编译错误System.out.println(Moo.b);}
}//演示静态方法何时用
class Noo{int a; //实例变量(描述对象的属性)//在show()中访问对象的属性a了,说明show()与对象有关,不能设计为静态方法void show(){System.out.println(a);}//在plus()中并没有访问对象的属性,说明plus()与对象无关,可以设计为静态方法static int plus(int num1,int num2){int num = num1+num2;return num;}
}public class StaticDemo {public static void main(String[] args) {Moo.test(); //常常通过类名点来访问}
}
静态块 由static修饰 属于类 ,在类被加载期间自动执行,一个类只被加载一次,所以 组成:由static 和一组大括号组成
何时用:初始化/加载静态资源(图片、音频、视频等)
案例:
//演示静态块
class Poo{static{System.out.println("静态块");}Poo(){System.out.println("构造方法");}
}public class StaticDemo {public static void main(String[] args) {//1)加载Poo.class到方法区中,同时自动执行静态块//2)new Poo()时,自动调用构造方法Poo o4 = new Poo();//1)new Poo()时,自动调用构造方法Poo o5 = new Poo();//1)new Poo()时,自动调用构造方法Poo o6 = new Poo();}
}
5 this(指代当前对象)
this:指代当前对象,哪个对象调用方法它指的就是哪个对象 ,
注意:只能用在方法中,方法中访问成员变量之前默认有个this.
this 的用法:
this.成员变量名--------------访问成员变量
( 当成员变量和局部变量同名时,若想访问成员变量则this不能省略,其它一般省略 )
this.方法名()------------------调用方法
this()----------------------------调用构造方法
this 用法案例
class Student {//成员变量String name;int age;String address;//构造方法Student(String name,int age,String address){this.name = name; //zs.name="zhangsan"this.age = age; //zs.age=25this.address = address; //zs.address="LF"}//方法void study(){System.out.println(name+"在学习...");}void sayHi(){System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address);}
}//构造方法和this的演示
public class ConsDemo {public static void main(String[] args) {//Student zs = new Student(); //编译错误,Student类没有无参构造Student zs = new Student("zhangsan",25,"LF");Student ls = new Student("lisi",26,"JMS");zs.sayHi();ls.sayHi();}
}
6 super (当前对象为超类对象)
super的用法
super.成员变量名---------访问超类的成员变量(一般不用,了解)
super.方法名()-----------调用超类的方法
super()------------调用超类的构造方法
注:super方法 也可以向上造型 ,具体案例看向上造型案例
7 static final (修饰常量)
定义:必须声明同时初始化,由类名点来访问,不能被改变。建议:所有字母都大写
作用:编译器在编译时会将常量直接替换为具体的值,效率高
何时用:数据永远不变,并且经常使用
8 abstract(抽象的)
--抽象方法:上文方法中已提到,
--抽象类:由abstract修饰 ,包含抽象方法的类必须是抽象类且抽象类不能被实例化(new对象) ; 抽象类是需要被继承的,派生类:
抽象类是需要被继承的,派生类:
重写所有抽象方法-----------------变不完整为完整
也声明为抽象类--------------------一般不这么做
意义: 封装共有的属性和行为---------------代码复用
为所有派生类提供统一的类型------向上造型(代码复用)
可以包含抽象方法,为所有派生类提供统一的入口(能点出来),同时达到强制必须重写的目的(相当于制定了一个标准)
9 访问控制修饰符
public 公开的 任意类中
protected:受保护的,本类、派生类、同包类
默认的:什么也不写,本类、同包类
private:私有的,本类
访问控制符访问权限:public >protected>默认的>private
六 接口
定义:是一种数据类型(引用类型)且由interface修饰,只能包含常量和抽象方法
案例
//演示接口的语法:
interface Inter{
public static final int NUM = 5;
public abstract void show() ;}
注意要点:
接口中的数据,默认都是常量。接口中的方法,默认都是抽象的。
接口中的所有内容的访问权限都一-定是public的
案例
int COUNT = 5; // 默认pubZic static final
void test(); // 默认public abstract
//int number; //编译错误,常量必须声明同时初始化
//void show(){} //编译错误,抽象方法不能有方法体
设计规则
接口即不能实例化也不能new对象 若想实例化 则需执行如下步骤
1.接口是需要被实现/继承的,实现类/派生类
2 必须重写所以抽象方法(implements 实现)
一个类可以实现多个接口,用逗号分隔,若又继承又实现时,应先继承后实现
接口可以继承接口
对象可以向上造型为:超类+所实现的接口
案例
//演示接口的多实现:
interface Inter2{void show();
}
interface Inter3{void test();
}
abstract class Boo{abstract void say();
}
class Coo extends Boo implements Inter2,Inter3{public void show(){}public void test(){}void say(){}
}
类型间关系
类和类------------继承extends
接口和接口------继承xtends
类和接口------------实现implemnents
设计规则
将所有派生类所共有的属性和行为,抽到超类中------抽共性
若对象的行为都一样,设计为普通方法若对象的行为都不一样,设计为抽象方法
将部分派生类所共有的属性和行为,抽到接口中接口是对继承单根性的扩展--------实现多继承接口相当于制定了一个标准、规范
七 多态
意义
同一个对象被造型为不同的类型时,有不同的功能
同一类型的引用在指向不同的对象时,有不同的实现 ----行为的多态:cut()、getImage()、move()......-----所有抽象方法都是多态的
向上造型/自动类型转换
超类型的引用指向派生类的对象
能点出来什么,看引用的类型
能造型成为的类型有:超类+所实现的接口
强制类型转换,成功的条件只有如下两种:
引用所指向的对象,就是该类型
引用所指向的对象,实现了该接口或继承了该类
注:强转时若不符合如上两个条件,则发生ClassCastException类型转换异常
建议:在强转之前先通过instanceof判断引用的对象是否是该类型
何时强转:当你想访问的东西超类中没有,就需要强转(哪个类中有就转成哪个类型)
案例:
public class MultiTypeDemo {public static void main(String[] args) {Aoo o = new Boo();Boo o1 = (Boo)o; //引用o所指向的对象就是Boo类型Inter o2 = (Inter)o; //引用o所指向的对象实现了Inter接口//Coo o3 = (Coo)o; //运行时发生ClassCastException类型转换异常if(o instanceof Coo){ //falseCoo o4 = (Coo)o;}else{System.out.println("o不是Coo类型");}}
}interface Inter{
}
class Aoo{
}
class Boo extends Aoo implements Inter{
}
class Coo extends Aoo{
}
更多推荐
java 面向对象总结
发布评论