文章目录
- 面向对象
- 类与对象
- 构造方法
- this关键字
- 垃圾回收
- 成员内部类
- 局部内部类
- 匿名内部类
- 继承
- super关键字
- 抽象类
- 接口
- 包
- 导包(import)
- 修饰符(final,static)
- 多态
- super关键字和this关键字的区别
面向对象
一·面向对象的定义:
创建对象可以是事还可以是物。在程序中使用对象来映射现实中的事物,使用对象来描述之间联系。
二.面向对象的特点:封装性
封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节。
继承性
主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下对原有类的功能进行扩展。
多态性
是指在程序中允许重名现象,它是指在一个类定义的属性和方法在不同的类中具有不同的意义。
类与对象
面对对象的编程思想,力图让程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出两个概念。即类和对象。其中对某一类的事物抽象描述,而对象用于表示现实中该类事物的个体。
类的定义:
在面向对象的思想中,最核心的就是对象。为了在程序中创建对象。首先需要定义一个类。类是对象的抽象。它用于描述一组对象的共同特征和行为。类可以定义成员变量和成员方法。其中成员变量用于描述用于描述对象的特征,也被称作属性;成员方法用于描述对象行为,可简称为方法。
class student{
int age;//定义int类型变量age
String name;//定义String类型变量name;
void introduce(){//定义方法
System.out.println("大家好,我今年"+age+"岁,"+"叫"+name);
}
}
上面定义了一个类,其student是类名,age,name是成员变量。introduce()是方法,它可以之间访问成员变量age,name。
对象的创建和使用
程序中可以使用new关键字创建一个对象。
格式如下
类名 对象名称 = new 类名 ( );
通过下面的例子看下(在上面我们已经创建好方法,现在只需引用就ok)
class Exception{
public static void main(String[] args){
student s1=new student();//创建对象
student s2= new student();
s1.age=13;//赋值
s1.name=大大;
s2.name=小小;
s1.introduce();//调用对象的方法
s2.introuduce();
}
}
执行后的结果如下,因为s2的年龄没有赋值,Java虚拟机自动给它初始化,也就是赋值为0
在实例化对象时,Java虚拟机会自动为成员变量进行初始化,针对不同类型的成员变量,Java虚拟机会赋予不同的初始值。
成员变量类型 | 初始值 |
byte | 0 |
short | 0 |
int | 0 |
fong | 0L |
double | 0D |
char | 空字符,’\u0000’ |
boolean | false |
引用数据类型 | null |
当对象被实例化,第一次调用方法的属性,第二次也是调用它,辣么它就出现null。(当一个变量的值为null,则表示该变量不指向任何一个对象)如果这个变量为null,被引用的对象叫做垃圾,不能再调用,成为垃圾对象。
类的设计
在Java中,对象是通过类创建出来的。因此,在设计类的时候很重要。
设置一个动物类(animal),再定义两个属性name和action
class animal{
String name;
void shout(){
System.out.println(name+"现在在叫");
}
}
类的封装
(在设定一个类的时候,应该对成员的访问做出限定,不允许外界访问。这就需要类的封装。)
根据上面一个设计的animal类创建对象,并访问该对象的成员。如下面案例所示
public class Example{
public static void main(String[] args){
Animal a1=new animal();
a1.name="哈士奇";
a1.shout();
}
}
运行如下:
类的封装是指在定义一个类时,将类中的属性私有化,即使用private关键字来修饰。私有属性只能在它所在的类中访问,如果外界想要访问,需要提供一些使用public修饰方法,其中包括用于获取属性值事物getXxx方法和设置属性值的setXxx方法。
package 案例;
class animal{
private String name;//将name的属性私有化
//下面时公有方法的getName和setName
private String getName() {
return name;
}
public void setName(String suName) {
name=suName;
}
public void shout(){
System.out.println(name+"现在在叫");
}
}
public class Example{
public static void main(String[] args){
animal su=new animal();
su.setName("哈士奇");
su.shout();
}
}
构造方法
(构造方法是类的一个特殊成员,在实例化对象时被自动调用。)
构造方法定义:
- 方法名与类名相同
- 在方法名的前面没有返回值类型的说明
- 在方法中不能使用return语句返回一个值。但是可以单独写return来作为方法的总结。
package 案例;
class person{
public person() {
System.out.println("无参的方法被调用了....
");
}
}
public class Example{
public static void main(String[] args){
person p1=new person();
}
}
在一个类中,不仅可以定义一个无参的构造方法,还可以定义一个有参的构造方法。
package 案例;
class person{
int age;
public person(int a) {
age=a;
}
public void introduce() {
System.out.println("我今年"+age+"岁啦!");
}
}
public class Example{
public static void main(String[] args){
person p1=new person(18);
p1.introduce();
}
}
构造的方法的重载
与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以调用不同的构造方法为不同属性赋值。
package 案例;
class person{
int age;
String name;
public person(int a,String b) {
age=a;
name=b;
}
public person(String b) {
name=b;
}
public void person1(int a,String b) {
age=a;
name=b;
}
public void introduce() {
System.out.println("我今年"+age+"岁啦!"+"我叫"+name);
}
}
public class Example{
public static void main(String[] args){
person p1=new person("大大");
person p2=new person(19,"小小");
p1.introduce();
p2.introduce();
}
}
构造方法的格式:
//第一种格式:
class 类名{
}
//第二种格式:
class 类名{
public 类名(){
}
}
this关键字
常见用法:
- 通过this关键字可以明确地去访问一个类的成员变量,解决与局部变量名称冲突问题.
class student{
String name;
public person(String name){
this.Name=Name;
}
public int getName(){
return this.Name;
}
}
- 通过this关键字调用成员方法。
class student{
public void this.openMouth(){
}
}
public void introduce(){
this.openMouth();
}
- 构造方法是在实例化对象时被Java虚拟机自动调用的,在程序中不能像调用其他的构造方法。但是可以通过一个构造方法使用this([参数1,参数2…])的形式调用其他的构造方法。
class student{
public student(){
Systm.out.println("无参的方法被调用了...");
public student(String name){
this();//调用无参的构造方法
System.out.println("有参的方法被调用了...");
}
}
public class Example{
public static void main(String[] args){
student s1= new student("itcast");//实例化对象
}
}
在使用this的要注意
- 只能在构造方法中使用this调用其他的构造方法,不能在成员变量中使用
- 在构造法方法中,使用this调用构造方法的语句必须于第一位,且只能出现一次。
public student(){
String name="哒哒";
this(name);//调用有参的构造方法,由于不在第一行,编译错误!
}
- 不能在一个类的两个构造方法中使用this互相调用。
class Student{
public student(){
this("哒哒");//调用有参的构造方法
System.out.println("无参的构造方法被调用了...");
}
public Student(String name){
this();//调用无参的构造方法
System.out.println("有参的构造方法被调用了...");
}
}
垃圾回收
除了等待Java虚拟机进行自动垃圾回收,还可以调用System.gc()来通知Java虚拟机立即进行垃圾回收。当一个对象在内存中释放时,它的finalize()方法会被自动调用,因此可以在类中通过定义finalize()方法来观察对象何时被释放。
public student{
//定义finalize方法在垃圾回收前被调用
public viid finalize(){
System.out.println("对象被作为垃圾对象回收...");
}
}
public class Example{
public static void main(String[] args){
//两个创建对象
student s1= new student();
student s2=new student();
//将下面变量置为null;
s1=null;
s2=null;
//调用方法进行垃圾回收
System,gc(){
for(int i=0;i,1000000;i++){
//为了延长程序运行时间
}
}
}
}
成员内部类
在Java中,允许在一个类的内部定义类,这样的类称作内部类,这个内部类所在的类称作外部类。内部类的格式
public class 类名{
修饰符 class 类名{
}
}
根据内部类的位置,修饰符和定义的方式可分为成员内部类,静态内部类,静态内部类,方法内部类。
在一个类中除了可以定义义成员变量,成员方法外,还可以定义类,这样的类被称作成员内部类。在成员内部类中,可以访问外部类的所有成员。
class Outer{
private int num=4;//定义类的成员变量
//下面的代码块定义成员方法,方法中访问内部类
public void test(){
Inner inner=new inner();
inner.show();
}
//下面的代码定义了一个成员内部类
class Inner{
void show(){
//在成员内部类的方法访问外部类的成员变量
System.out.println("num="+num);
}
}
}
public class Example{
public static void main(String[] args){
Outer outer=new Outer();//创建外部类对象
outer.test();
}
}
内部类可以在外部类中被使用,并能访问外部类的成员,包括私有。如果想通过外部类去访问内部类,则需要通过外部类对象去创建内部类对象,创建内部类对象的具体格式如下:
外部类名.内部类名 变量名 = new 外部类名() .new 内部类名();
class Outer{
private int num=4;//定义类的成员变量
//下面的代码块定义成员方法,方法中访问内部类
public void test(){
Inner inner=new inner();
inner.show();
}
//下面的代码定义了一个成员内部类
class Inner{
void show(){
//在成员内部类的方法访问外部类的成员变量
System.out.println("num="+num);
}
}
}
public class Example{
public static void main(String[] args){
Outer outer o1=new Outer().new Inner() ;//创建外部类对象
outer.show();
}
}
局部内部类
局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
匿名内部类
前提:
存在一个类或者接口,这里的类可以是具体类也可以是抽象类格式:
new 类名或者接口名(){
重写方法;
};
本质:
是一个继承了该类或者实现了该接口的子类匿名对象。
下面是例子。
package 案例;
import java.lang.reflect.Method;
class Outer { //创建外部类
public void method() {
new Inter() {
@Override
public void show() {//创建内部类
System.out.println("猪猪呀");
}
}.method();//调用方法
}
}
//测试类
public class Example{
public static void main(String[] args){
Outer o=new Outer();//创建对象
o.method(); //调用方法
}
}
再创建Inter接口
package 案例;
public interface Inter {
void show() ;
}
如果要多打印几句数据语句,如下:
package 案例;
import java.lang.reflect.Method;
class Outer { //创建外部类
public void method() {
Inter i=new Inter() {
@Override
public void show() {//创建内部类
System.out.println("猪猪呀");
}
};
i.show();
i.show();
}
}
public class Example{
public static void main(String[] args){
Outer o=new Outer();//创建对象
o.method(); //调用方法
}
}
小总结:匿名内部类后面的花括号}要加封号,如};。如果是在匿名内部类中创建变量,格式如下:
类名或接口名 变量=new 类名或接口名(){
重写方法
}.方法(接口里的);
继承
继承的概念:
在程序中,继续描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。(可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法)
父类被称为基类,超类;子类被称为派生类。
继承中子类的特点:子类可以有父类的内容,子类也可以有自己特有的内容。
继承的好处和弊端:
继承好处:
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
继承弊端:
- 继承让类与类之间产生了关系,类的耦合性增强了。当父类发送变化时子类实现也不得不跟着变化,削弱了子类的独立性
在Java中,类的继承是指在一个现有类的基础上构建一个新的类,构建出来的新类被称为子类。现有类被称作父类,子类会自动拥有父类所有继承的属性和方法。在程序中,声明一个类继承另外一个类,需要使用extends关键字。
继承格式:
public class 子类名 extends 父类名()
继承中变量的访问特点:
在子类方法中访问一个变量:在子类局部,成员范围内找,再父类成员范围类找。
继承中构造方法的访问特点:
- 子类中所有的构造方法默认都会访问父类中无参的构造方法
原因:
- 因为子类会继承父类中数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个子类构造方法的第一条语句默认都是:super()
- 父类中没有无参构造方法,只有带参数构造方法
- 通过使用super关键字去显示的调用父类的带参构造方法
- 在父类中自己提供一个无参构造方法。
继承中成员方法的访问特点:
通过子类对象访问一个方法:在子类成员范围找,在父类成员范围找。如果,没有就报错。
案例
//定义Animal类
class PersonA{
String name;//定义name属性
//定义人的行为
void action(){
System.out.println("A在唱歌");
}
}
//定义Biu类继承PersonA类
class Biu extends PersonA{
//定义一个打印name的方法
public void printName{
System.out.println("她叫"+name)
}
}
//定义测试类
public class Example{
public static void main(String[] args){
Biu b=new Biu(); //创建一个biu类的实例对象
b.name="花花";//为biu类的name的属性进行赋值
b.PrintName();//调用biu类的printName()方法
b.action();//调用biu类的继承的action()方法
}
}
注意:
1.在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类。
class A{}
class B{]
class c extends A,B{}//c类不可以同时继承a和b类
- 多个类可以继承一个父类。
class A{}
class B extends A{}
class C extends A{}//b类和c类都可以继承类a
- 在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类。
class A{}
class B extends A {} //类b继承a,类b是a的子类
class C extends B {}//类c继承b,类c是类b的子类,也是a的子类。
重写父类的方法
在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即父类的重写。
但需要注意的是,在子类中重写的方法需要父类被重写的方法具有相同的方法名,参数类表以及返回值类型。
class PersonA{
void action(){
System.out.println("她在玩");
}
}
class biu extends PersonA{
public static void main(String[] args){
void action(){
System.out.println("跳舞...");
}
}
public class Example{
Biu b= new Biu();
b.action();
}
}
子类重写父类的方法时,不能使用比父类中被重写的方法更严格的访问权限。如:父类中的方法是public的,但子类的方法就不能是private的。
super关键字
定义:
用于访问父类的成员。(代表父类存储空间的标识)
- 使用super关键字访问父类的成员变量和成员方法。具体格式如下
super.成员变量
super.成员方法([参数1,参数2....])
package 案例;
//定义Animal类
class Animal{
String name="动物";
//定义动物叫的方法
void shout() {
System.out.println("动物发出声音");
}
}
//定义cat类继承Animal类
class cat extends Animal{
String name="猫科";
//重写父类的shout的方法
void shout(){
super.shout(); //访问父类的成员方法
}
//定义打印name的方法
void biuName() {
System.out.println("name="+super.name);
}
}
//定义测试类
public class Example {
public static void main(String[] args) {
cat c=new cat();//创建对象
c.shout();//调用cat对象重写的shout()方法
c.biuName();//调用cat的对象的biuName()方法
}
}
- 使用super关键字访问父类的构造方法。具体格式如下:
super([参数1,参数2....])
package 案例;
//定义Animal类
class Animal{
//定义有参数的构造方法
public Animal(String name) {
System.out.println("它是一只"+name);
}
}
//定义cat类继承Animal类
class Cat extends Animal{
public Cat() {
super("短耳猫");//调用父类有参的构造方法
}
}
//定义测试类
public class Example {
public static void main(String[] args) {
Cat c=new Cat();//实例化子类cat对象
}
}
抽象类
当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式时无法确定的。(在Java中,一个没有方法提的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类)
针对上面描述的情况,Java允许定义方法时不写方法体,称为为抽象方法。抽象方法必须使用abstract关键字来修饰。
abstract void 方法();//定义抽象方法 方法()
当一个类包含了抽象方法,该类必须使用abstract关键字来修饰,使用abstract关键字修饰的类称为抽象类。
//定义抽象类Animal
abstract class Animal{
//定义抽象方法shout()
abstract int shout();
}
抽象类的特点:
- 抽象类和抽象方法必须使用abstract关键字修饰
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能被实例化,但是他可以参照多态的方式,通过子类对象实例化,这叫抽象类多态
- 抽象类的子类,要么重写抽象类中所有的方法,要么它本身是抽象类。
抽象类中的成员特点:
- 成员变量:是能是常量,因为有默认修饰符(public static final)
- 成员变量可以是变量,也可以是常量
- 构造方法不能实例化,它的作用是用子类访问父类数据初始化
- 成员方法可以有抽象方法,限定子类必须完成某些动作,也可以有非抽象方法:提高代码复用性。
接口
如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义。即是接口。接口时由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。
在定义接口时,需要使用interface关键字来声明,其语法格式如下:
[public] interfance 接口名[extends 接口1,接口2...]{
[public] [static] [final] 数据类型 常量名=常量值;
[public] [abstract] 返回值 抽象方法名(参数列表);
- 接口不能实例化,需要参照多态的方式,通过实现类对象实例化,这叫接口多态。
实例化的形式:
具体类多态,抽象类多态,接口多态。多态的前提:
有继承或者实现关系;有方法重写;有父(类/接口)引向指向(子/实现)类对象。 - 接口实现类:要么重写接口中所有的抽象方法,要么本身是抽象类。
接口的成员特点:
- 成员变量:只能是常量,它有默认修饰符:(public static final)
- 构造方法:接口没有构造方法,因为接口主要是对进行抽象的,是没有具体存在。一个类如果没有父类,默认继承自object类
- 成员方法:只能是抽象方法,默认修饰符:public abstract
包
包的概念和使用:
包其实就是文件夹,它的作用时对类进行分类管理。
包的定义格式:
package 包名(多级包用.分开)
带包的java 类编译和执行
- 手动建包:按照以前的格式编译Java文件–手动创建包–把class文件放到包的最里面–带包执行
- 自动建包:javac-d-包名.java
导包(import)
目的:使用不同包下的类时,使用的时候要写类的全路径,为了简化所以用导包。
导包的格式:
import 包名;
修饰符(final,static)
分类:
权限修饰符和状态修饰符
权限修饰符:
状态修饰符:
final:
final关键字可用于修饰类,变量和方法,它有“无法改变”或者“最终”的含义。
final关键字修饰类
Java中的类被final关键字修饰后,该类不可以被继承,也就是不能够派生子类。
final关键字修饰方法
当一个类的方法被final关键字修饰后,这个类子类将不能重写该方法。
final关键字修饰变量
Java中被final修饰的变量称为常量,它只能赋值一次,也就是说final修饰的变量一旦被赋值,其值不能改变。若再次对变量进行赋值,则程序会在编译时报错
是最终的意思,可以修饰成员方法,成员变量,类。
- 修饰方法:表明该方法是最终态,不能被重写
- 修饰变量:表明该变量是常量,不能被赋值
- 修饰类表明该类是最终类,不能被继承。
final修饰局部变量
- 变量是基本类型:final修饰的是基本类型的
数据值不能发生改变
- 变量是引用类型:final修饰指的是引用类型的
地址值不能发生改变,但是地址里面的内容是可以改变。
static:
是静态的意思,可以修饰成员方法,成员变量。
static修饰特点:
- 该类的所有对象共享
- 可以通过类名,对象进行调用。
static 访问特点:静态成员方法只能访问静态成员。但是非静态成员方法都可以访问静态和非静态的成员变量和成员方法。
它用于修饰类的成员,如成员变量,成员方法以及代码块,被static修饰的成员具备一些特殊性。
静态变量
在一个Java类中,可以使用static关键字来修饰成员变量,该变量称为静态变量。静态变量被所有实例共享,可以使用”类名.变量名“的形式来访问。
class student{
static String schoolName;//定义静态变量schoolName
}
public class Example{
public static void main(String[] args){
student s1=new student();//创建学生对象
student s2=new student();
//为静态变量赋值
student.schoolName="希望小学";
System.out.println("我的学校是"+s1.schoolName);
System.out.println("我的学校是"+s2.schoolName);
}
}
上面用student类中定义了一个静态变量schoolName,用于表示学生所在的学校,它被所有的实例化共享。由于schoolName静态变量,因此可以通过student的实例化对象进行调用。
static关键字只能用于修饰成员变量,不能用于修饰局部变量,否则编译会报错。
public class Student{
//静态成员方法
public void study{
static int num=10;//这行代码是非法的,编译会报错。
}
}
静态方法
只要在类中定义的方法前加上static关键字即可,通常这种方法成为静态方法。同静态方法可以使用”类名.方法名“的方法来访问,也可以通过类的实例化对象访问。
public student{
public static void sayHellow(){
System.out.println("hello");
}
}
class Example{
public static void main(String[] args){
student.sayHellow();
student s1=new student();
s1.sayHellow();
}
}
在一个静态方法中只能访问static修饰的成员,原因在于没有被static修饰的成员需要创建对象才能访问。静态方法不需要创建对象也可以调用。
静态代码块
在Java类中,使用一对大括号包围起来的诺干行代码被称为代码块。当类被加载时,在类被加载时,静态代码块会执行,由于类只能加载一次,因此静态代码块只执行一次。在程序中,通常会使代码块来对类的成员变量进行初始化。
class Example(){
static{
System.out.println("测试类的静态代码块执行了");
}
public static void main(String[] args){
persom p1=new person();
person p2=new person();
}
}
class Person{
static{
System.out.println("Peerson类中的静态代码块执行了");
}
}
多态
概述
:同一个对象,在不同时刻表现出的不同形态。
多态的前提和体现:
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
多态中成员访问特点:
- 成员变量:编译看左边,执行看左边
- 成员方法:编译看左边,执行看右边
多态的好处和弊端:
好处:提高了程序的扩展性(在定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作)
弊端:不能使用子类特有的功能
多态的转型
- 向上转型:从子到父(父类引用指向子类对象)
- 向下转型:从子到父(父类引用转为子类对象)
super关键字和this关键字的区别