封装
概述
是面向对象三大特征之一(封装,继承,多态)
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的getXxx()/setXxx()方法
好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性
构造方法
概述
构造方法是一种特殊的方法
作用:创建对象
格式:
public class 类名{
修饰符 类名( 参数 ) {
}
}
功能:主要是完成对象数据的初始化
注意事项
1、构造方法的创建
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
2、构造方法的重载
如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法
3、推荐的使用方式
无论是否使用,都手工书写无参数构造方法
标准类制作
成员变量
使用private修饰
构造方法
提供一个无参构造方法
提供一个带多个参数的构造方法
成员方法
提供每一个成员变量对应的setXxx()/getXxx()
提供一个显示对象信息的show()
创建对象并为其成员变量赋值的两种方式
无参构造方法创建对象后使用setXxx()赋值
使用带参构造方法直接创建带有属性值的对象
字符串
API:应用程序接口
java API:JDK中提供的各种功能的java类
String:内容是不可变的
概述
String类代表字符串,java程序中的所有字符串文字都被实现为此类的实例。即是java程序中所有的双引号字符串,都是String类的对象。
字符串特点
字符串不可变,他们的值在创建后不能被更改
虽然String的值是不可变的,但是它们可以被共享
字符串效果上相当于字符数组(char []),但是底层原理是字节数组(byte [])
构造方法
public String()//空白对象
public String(char[] chs)//依字符数组,创建对象
public String(byte[] bys)//依字节数组,创建对象
String s="abc"//直接赋值
对象的特点
通过new 创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
以""方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护
字符串的比较(==)
基本类型:比较数据值是否相同
引用类型:比较地址值是否相同
字符串是对象,它比较内容是否相同,是通过一个方法来实现的,这个方法叫:equals()
public boolean equals(Object anObject)
StringBuilder:内容是可变的
概述:是一个可变的字符串类,即是指对象中的内容是可变的
构造方法
public StringBuilder()// 空白对象
public StringBuilder(String str)//据字符串内容创建可变字符串对象
添加和反转
public StringBuilder append(任何数据类型)//添加数据,并返回对象本身
public StringBuilder reverse()//返回相反的字符序列
String与StringBuilder的相互转换
StringBuilder——String
通过toString()
String——StringBuilder
通过构造方法
例子:
(1)定义Student类,有4个属性:
String name;
int age;
String school;
String major;
//(2)定义Student类的3个构造器:
第一个构造器Student(String n, int a)设置类的name和age属性;
第二个构造器Student(String n, int a, String s)设置类的name, age 和school属性;
第三个构造器Student(String n, int a, String s, String m)设置类的name, age ,school和major属性;
//(3)在main方法中分别调用不同的构造器创建的对象,并输出其属性值
public class Student {
String name;
int age;
String school;
String major;
//(2)定义Student类的3个构造器:
public Student(String n, int a) {
this.name = n;
this.age = a;
}
public Student(String n, int a, String s) {
this.name = n;
this.age = a;
this.school = s;
}
public Student(String n, int a, String s, String m) {
this.name = n;
this.age = a;
this.school = s;
this.major = m;
}
public void show() {
System.out.println("姓名:" + name + "," + "年龄:" + age + "," + "学校:" + school + "," + "学科:" + major);
}
//测试
public class StudentDemo {
public static void main(String[] args) {
Student s1=new Student("张良",15);
Student s2=new Student("张良",15,"一中");
Student s3=new Student("张良",15,"一中","国学");
s1.show();
s2.show();
s3.show();
}
}
继承
概述
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可在子类中重新定义,追加属性和方法
格式:public class 子类名 extends 父类名{}
父类也称为基类、超类,子类也称派生类
好处和弊端
好处
提高了代码的复用性(多个类相同的成员可以放在同一个类中)
提高了代码的维护性(如皋方法的代码需要修改,修改一处即可)
弊端
继承让类和类之间产生了关系,类的耦合性增强,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性。
什么时候使用继承?
继承关系的体现: is a
假设法:两个类A、B,如皋满足A是B的一种,或者B是A的一种,就说他们存在继承关系,这个时候就可考虑使用继承来体现,否者就不能滥用。
super关键字
super关键字和this关键字的用法相似
this:代表本类对象的引用
访问成员变量:this.成员变量
访问构造方法:this(...)
访问成员方法:this.成员方法()
super:代表父类存储空间的标识(即是父类对象引用)
访问成员变量:super.成员变量
访问构造方法:super(...)
访问成员方法:super.成员方法()
方法重写
概述
子类中出现了和父类中一模一样的方法声明
应用
当子类需要父类的功能,而功能主体子类有自己特有的内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,有定义了子类特有的内容
@Override
是一个注释
可以帮助我们检查重写方法的方法声明的正确性
注意事项
私有方法不能被重写(父类私有成员子类是不能继承的)
子类方法访问权限不能更低(public>默认>私有)
注意事项
java中类只支持单继承,不支持多继承
java中类支持多层继承
访问特点
变量
子类方法中访问一个变量
子类局部范围找
子类成员范围找
父类成员范围找
如皋都没有就报错(不考虑父类的父类)
构造方法
为什么子类中所有构造方法默认都会访问父类中无参的构造方法?
因为子类会继承父类的数据,还可能会使用父类的数据。所以,子类初始化之前,一定要完成父类数据的初始化。
每一个子类构造方法的第一语句默认是super()
如皋父类没有无参构造方法,只有带参构造方法,该怎么办?
通过实验super关键字去显示的调用父类的带参构造方法
在父类自己提供一个无参构造方法
成员方法
通过子类对象访问一个方法
子类局部范围找
子类成员范围找
父类成员范围找
如皋都没有就报错(不考虑父类的父类)
修饰符
包
概述:即是文件夹;对类进行分类管理
使用
定义格式:package 包名;(多级用“.”隔开)
带包的java类编译和执行
手动建包
自动建包:javac -d. helloworld.java
导包
概述:为了简化带包操作,java就提供了导包功能
使用
格式:import 包名;
修饰符
权限修饰符
private
同一个类中
默认
同一个类中
同一个包中子类无关类
protected
同一个类中
同一个包中子类无关类
不同包的子类
public
同一个类中
同一个包中子类无关类
不同包的子类
不同包的无关类
状态修饰符
final
final关键字去是最终的意思,可以修饰成员方法、成员变量、类
修饰特点
修饰方法:表明该方法是最终方法,不能被重写
修饰变量;表示该变量是常量,不能再次被赋值
修饰类:表明该类是最终类,不能被继承
修饰局部变量
变量是基本类型
final修饰指的是基本类型的数据值不能发生改变
变量是引用类型
final修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
static
static关键字是静态的意思,可以修饰成员方法,成员变量
static的修饰特点
被类的实验对象共享(判断是否使用静态关键字的条件)
可以通过类名调用(当然也可以通过对象名调用)
static访问特点
静态成员方法只能访问静态成员
例子:根据下图实现类。在CylinderTest类中创建Cylinder类的对象,Cylinder类继承Circle类,设置圆柱的底面半径和高,并输出圆柱的体积。
Circle (圆)
-radius :double
Circle(): 构造器,将radius属性初始化为1
+setRadius(double radius) : void
+getRadius(): double
+findArea():double 计算圆的面积
Cylinder (圆柱)
-length:double
Cylinder(): 构造器,将length属性初始化为1
+setLength(double length):void
+getLength():double
+findVolume() :double 计算圆柱体积
public class Circle {
private double radius;
public Circle() {
}
public Circle(double radius) {
this.radius =1;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return radius*radius*3.14;
}
}
//
public class Cylinder extends Circle{
private double length;
public Cylinder(){}
public Cylinder(double radius, double length) {
super(radius);
this.length = 1;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double findVolume(){
return findArea()*length;
}
}
//
public class CylinderTest {
public static void main(String[] args) {
Cylinder c=new Cylinder();
c.setRadius(5);
c.getRadius();
c.findArea();
c.setLength(10);
c.getLength();
c.findVolume();
System.out.println("圆柱的体积:"+c.findVolume());
}
}
多态
概述
什么是多态
同一个对象,在不同时刻表现出来的不同形态
多态的前提
- 要有继承或实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
成员访问特点
成员变量
编译看父类,运行看父类
成员方法
编译看父类,运行看子类
好处与弊端
好处
提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
弊端
不能使用子类的特有成员
转型
向上转型
父类引用指向子类对象就是向上转型
向下转型
格式:子类型 对象名 = (子类型)父类引用;
练习:
定义三个类,父类GeometricObject代表几何形状,子类Circle代表圆形,MyRectangle代表矩形。
GeometricObject:
private String color;
private int weight;
提供有参/无参构造方法,setter/getter,提供findArea()方法:计算面积用的
Circle:
private double radius;
提供有参(含父类)/无参构造方法,setter/getter,重写findArea()方法:计算圆面积
MyRectangle:
private double width;
private double height;
提供有参(含父类)/无参构造方法,setter/getter,重写findArea方法:计算矩形面积
/*
定义一个测试类GeometricTest,编写equalsArea方法测试两个对象的面积是否相等,编写displayGeometricObject方法显示对象的面积。(注意:通用性!)*/
public class GeometricObject {
private String color;
private int weight;
public GeometricObject() {
}
public GeometricObject(String color, int weight) {
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public double findArea() {
return 0.0;
}
}
//
public class Circle extends GeometricObject {
private double radius;
public Circle() {
}
public Circle(String color, int weight, double radius) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double findArea() {
return radius * radius * 3.14;
}
}
//
public class MyRectangle extends GeometricObject {
private double width;
private double height;
public MyRectangle(String color, int weight,double width, double height) {
super(color,weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public double findArea() {
return width*height;
}
}
//
public class GeometricTest {
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle c = new Circle("黑",2,1.5);
test.displayGeometricObject(c);
MyRectangle m = new MyRectangle("黑",3,4.2,5.3);
test.displayGeometricObject(m);
boolean isEquals = test.equalsArea(c,m);
System.out.println("c和m的面积是否相等:"+isEquals);
}
public boolean equalsArea(GeometricObject c, GeometricObject m){
return c.findArea() == m.findArea();
}
public void displayGeometricObject(GeometricObject o){
System.out.println("面积为:" + o.findArea());
}
}