面向对象三大特点:封装、继承、多态
封装概念
① 将东西包装在一起,然后以新的完整形式呈现出来:
将方法和字段一起包装到一个单元中,单元以类的形式实现;
② 信息隐藏,隐藏对象的实现细节,不让外部直接访问到;
③ 将数据和方法包装进类中,加上具体实现的隐藏,共同被称作封装,其结果是一个同时带有特征和行为的数据类型;
④ 定义类,定义其属性、方法的过程称为封装类;
信息隐藏式OOP最重要的功能之一,也是使用访问修饰符的原因;
信息隐藏的原因包括:
① 对模块的任何实现细节所作的更改不会影响使用该模块的代码;
② 防止用户意外修改数据;
③ 是模块易于使用和维护;
访问修饰符
① public:该类或非该类都均可访问;
② private:只有该类可以访问;
③ protected:该类及其子类的成员可以访问,同一个包中的类也可以访问;
④ 默认:同一包中的类可以访问;
属性封装的实现
① 修改属性的可见性来限制对属性的访问;
② 为每个属性创建一对赋值(setter)方法和取值(getter)方法,用于公开对这些属性的访问接口;
③ 在setter和getter方法中,根据需要加入对属性操作的限制;
要点:除非必须公开底层实现细节,否则应该将所有属性指定为private加以封装;使用属性封装,通过增加数据访问限制,增强了类的可维护性;
封装方法的目的
① 隐藏方法实现细节(方法体),向外部提供公开接口(方法头),以供安全;
② 简化调用,方便修改维护;
③ 根据需要,可以私有化方法以供类内部使用----帮助方法help;
public class TeacherDemo
{
public static void main(String []agrs){
Teacher t=new Teacher();
//t.name="张三";//不能直接赋值
t.setName("张三");
System.out.println(t.getName());
t.setAge(10);
System.out.println(t.getAge());
}
} class Teacher
{
private String name;
private int age;
public void setName(String tname){
name=tname;
}
public String getName(){
return name;
}
public void setAge(int tage){
if(tage<25)
{
System.out.println("年龄太小了");
age=25;
}
else
{
age=tage;
}
}
public int getAge(){
return age;
}
}
类的构造方法的概念和作用
① 构造方法负责对象初始化工作,为对象的属性赋合适的初始值;
② 创建对象时,其类的构造方法确保在用户操作对象之前,系统保证初始化的进行;
构造方法的语法规则
① 构造方法名与类名相同
② 没有返回类型
③ 方法实现主要为字段赋初值
构造方法的调用和特别:new操作符(返回新建实例的引用)
无参构造方法
public class ConstructorDemo
{
public static void main(String []agrs){
Person p=new Person();//实例化的时候是有初始值的int默认0,String默认null
p.setName("张三");
p.setAge(10);
System.out.println(p.toString());
}
} //当一个类没有显示声明一个构造方法时,系统会有一个默认的无参构造方法
class Person
{
private String name;
private int age;
private String city; //默认的构造方法,实例化时候会调用,此处不写也可以,系统已默认写好
public Person(){
System.out.println("Person");
} public void setCity(String pcity){
city =pcity;
}
public String getCity(){
return city;
} public void setName(String pname){
name=pname;
}
public String getName(){
return name;
} public void setAge(int page){
age=page;
}
public int getAge(){
return age;
} public String toString()
{
return "名字:"+name+",今年"+age+"岁,家住"+city;
}
}
带参构造方法
public class ConstructorDemo
{
public static void main(String []agrs){
//带参调用,若不写参数会报错,因为Person中只有一个带参的构造方法
Person p=new Person("张三",10,"杭州");
//1、在堆中开辟空间,给属性分配默认的初始值
//2、假设属性一开始就赋值了,就进行赋值工作
//3、调用构造方法对属性进行初始化
System.out.println(p.toString());
}
} class Person
{
private String name="李四";
private int age;
private String city; //带参数的构造方法
public Person(String pname,int page,String pcity ){
name=pname;
age=page;
city=pcity;
} public void setCity(String pcity){
city =pcity;
}
public String getCity(){
return city;
} public void setName(String pname){
name=pname;
}
public String getName(){
return name;
} public void setAge(int page){
age=page;
}
public int getAge(){
return age;
} public String toString()
{
return "名字:"+name+",今年"+age+"岁,家住"+city;
}
}
this关键字
特点:
①在类的方法中使用的this关键字代表的是调用此方法的对象的引用;
②this可以看作是一个变量,它的值是当前对象的引用;
③使用this可以处理方法中的成员变量和形参同名的问题;
④当方法内需要用到调用该方法的对象时,就可以用this;
⑤在类的构造方法中可以调用this([参数列表])来调用该类的指定构造方法。
public class ConstructorDemo
{
public static void main(String []agrs){
Person p=new Person("张三",10,"杭州");
System.out.println(p.toString());
}
} class Person
{
private String name="李四";
private int age;
private String city; //构造方法
public Person(){
System.out.println("无参构造方法");
} //带参数的构造方法
public Person(String name,int age,String city ){ this();//表示调用当前对象的无参构造方法,必须写在第一句 //此处将形参名称写成age与属性名相同
//age=age;//此处不会对属性重新赋值age=0
this.age=age;//此处对属性重新赋值age=10,this代表p
this.name=name;
this.city=city; } public void setCity(String city){
this.city=city;
}
public String getCity(){
return city;
} public void setName(String name){
this.name=name;
}
public String getName(){
return name;
} public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
} public String toString()
{
//默认前面都是有this的,可写可不写
System.out.println(this.getAge());
return "名字:"+this.name+",今年"+age+"岁,家住"+city;
}
}
static关键字
特点:
①用来修饰类的成员----修饰成员变量的称之为类变量(静态变量),修饰成员方法的称之为类方法(静态方法);
②当类被加载时就会被加载,优先于对象的存在;
③用来修饰语句块----称之为静态代码块。先于构造方法之前执行,只会执行一次,用来对静态成员做初始化;
④静态修饰的成员被所有的对象共享;
⑤调用的时候可以直接通过类名.成员来进行访问
static关键字注意事项
① 静态方法中只能访问外部的静态成员;
② 静态方法中不能出现this;
非静态
public class StaticDemo
{
public static void main(String []agrs){
Account acc1=new Account();
acc1.number1++;
acc1.showNumber1();
acc1.showNumber2(); Account acc2=new Account();
acc2.showNumber1();
acc2.showNumber2();
}
} class Account
{
public int number1=1;
public int number2=2;
public void showNumber1()
{
System.out.println(number1);
}
public void showNumber2()
{
System.out.println(number2);
}
}
静态1
public class StaticDemo
{
public static void main(String []agrs){
Account acc1=new Account();
acc1.number1++;
acc1.showNumber1();
//acc1.showNumber2(); Account acc2=new Account();
acc2.showNumber1();
//acc2.showNumber2();
}
} class Account
{
public static int number1=1;//静态变量(类变量),它不属于任何一个对象,被多个对象共享
public int number2=2;
public void showNumber1()
{
System.out.println(number1);
}
public void showNumber2()
{
System.out.println(number2);
}
}
静态2
public class StaticDemo
{
public static void main(String []agrs){
Account.number1++;
System.out.println(Account.number1);
Account.showNumber1(); Account acc1=new Account();
acc1.showNumber2(); Account acc2=new Account();
acc2.showNumber2();
}
} class Account
{
public static int number1=1;//静态变量(类变量),它不属于任何一个对象,被多个对象共享
public int number2=2;
//静态方法中不能使用非静态的变量
//静态方法中不能使用this
public static void showNumber1()
{
//showNumber2();//报错
System.out.println(number1);
//System.out.println(this.number2);//报错
} //非静态的方法可以访问静态的内容和非静态的属性和方法
public void showNumber2()
{
showNumber1();
System.out.println(number2);
System.out.println("非静态方法访问静态变量:"+number1);
} //构造方法
public Account(){
System.out.println("constructor");
} //static语句块
//在类被加载时就会执行,只会执行一次,用来对静态的变量赋值
//优先于构造方法执行
static{
System.out.println("static");
number1=100;
}
}
方法重载
多数程序设计语言要求为每个方法(函数)提供一个独一无二的方法名,不存在方法重载的概念
在Java中,规定方法签名是解析方法的规则而不是方法名,为方法重载开创了条件
方法重载使得在一个类中,方法名相同而参数列表不同的方法可同时存在,代表相似的行为和功能
重载overload概念:同一类中,同名不同参的方法称为重载方法
注意:仅有返回类型不同的方法不能称为重载,即方法重载必须方法签名不同
public class OverloadDemo{
public static void main(String []agrs){
Printer p=new Printer(2000);
p.print("hello");
p.print(10);
p.print("hello",10);
}
} class Printer{
private String brand="联想";
private double price; public Printer(double price){
this.price=price;
} public Printer(String brand,double price){
this.brand=brand;
this.price=price;
} public void print(String content){
System.out.println("字符串"+content);
} public void print(int content){
System.out.println("整型"+content);
} public void print(String str,int content){
System.out.println(str+"--"+content);
} public int print(int content,double d){
return content;
}
}