Java面向对象编程
在面向对象定义之中,也规定了一些基本的特征:
(1)封装:保护内部的操作不被破坏;
(2)继承:在原本的基础之上继续进行扩充;
(3)多态:在一个指定的范围之内进行概念的转换。
对于面向对象的开发来讲也分为三个过程:OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)。
1.类与对象的定义及使用
- 实例化对象之后,需要通过对象进行类中的操作调用,调用方法如下:
调用类中的属性:实例化对象.成员属性
调用类中的方法:实例化对象.方法名称()
class Person{ //定义一个类
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+",年龄:"+age);
}
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per =new Person(); //声明并实例化对象
per.name="张三"; //调用类中的属性
per.age=18; //调用类中的属性
per.tell(); //进行方法的调用
}
}
2.成员属性封装(private关键字)
- 设置属性的方法:public void setName(String n)
- 获取属性的方法:public String getName()
class Person { //定义一个类
private String name;
private int age;
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public void setName(String n) {
name = n;
}
public void setAge(int a) {
age = a;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per = new Person(); //声明并实例化对象
per.setName("张三"); //调用方法,属性被封装了
per.setAge(18); //调用方法,属性被封装了
per.tell(); //进行方法的调用
}
}
3.构造方法
- JAVA中构造方法的要求:
构造方法名称必须与类名称保持一致
构造方法不允许设置任何返回值类型,即没有返回值定义
构造方法在使用new实例化对象的时候是自动调用的
class Person { //定义一个类
private String name;
private int age;
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public Person(String n, int a) { //构造方法****
name = n;
age = a;
}
//setter,getter省略
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per = new Person("张三",18); //声明并实例化对象
per.tell(); //进行方法的调用
}
}
匿名对象
4.this关键字
(1)this调用本类属性
class Person { //定义一个类
private String name;
private int age;
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public Person(String name, int age) { //构造方法****
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per = new Person("张三",18); //声明并实例化对象
per.tell(); //进行方法的调用
}
}
(2)this调用本类方法
- 普通方法调用:(this.方法名称()):实例化对象产生之后就可以调用普通方法。
class Person { //定义一个类
private String name;
private int age;
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public Person(String name, int age) { //构造方法
this.setName(name); //调用普通方法****
this.setAge(age); //调用普通方法****
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per = new Person("张三",18); //声明并实例化对象
per.tell(); //进行方法的调用
}
}
- 构造方法调用:(this()):使用关键字new实例化对象的时候才会调用构造方法。(注意:this()必须放在首行)
class Person { //定义一个类
private String name;
private int age;
public Person() {
System.out.println("一个新的person类对象实例化了");
}
public Person(String name) {
this(); //调用本类无参构造****放在首行
this.name = name;
}
public Person(String name, int age) { //构造方法
this(name); //调用本类单参构造****放在首行
this.age = age;
}
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public void setName(String name) { //setter,getter可省略
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
public class JavaDemo { //主类
public static void main(String[] args) {
Person per = new Person("张三",18); //声明并实例化对象
per.tell(); //进行方法的调用
}
}
5.简单java类
- 简单java类结构如下
1.类名称一定要有意义,可以明确的描述某一类事物
2.类之中的都有的属性必须使用private进行封装,同时封装后的属性必须要提供有setter和getter
3.类之中可以提供有无数多个构造方法,但是必须要保留有无参构造方法(public Person(){})
4.类之中不允许出现任何的输出语句,所有获取的内容必须返回
5.【非必须】可以提供有一个获取对象详细信息的方法,暂时将此方法名称定义为个getInfo()
继承(extends)
- 子类继承父类
class Person { //定义一个类,父类
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
class Student extends Person { //studet是子类*****
}
public class Demo { //主类
public static void main(String[] args) {
Person per = new Person(); //声明并实例化对象
Student stu = new Student();
stu.setName("林大强");
stu.setAge(18);
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge());
}
}
- 子类扩充定义
class Person { //定义一个类
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
class Student extends Person { //studet是子类,person是父类
private String school; //子类扩充的属性******
public void setSchool(String school) {
this.school = school;
}
public String getSchool() {
return school;
}
}
public class Demo { //主类
public static void main(String[] args) {
Person per = new Person(); //声明并实例化对象
Student stu = new Student();
stu.setName("林大强");
stu.setAge(18);
stu.setSchool("家里蹲大学");
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge() + ",学校:" + stu.getSchool());
}
}
- 子类对象实例化流程
class Person { //定义一个类
public Person(){
System.out.println("一个新的person实例化对象产生了");
}
}
class Student extends Person { //studet是子类,person是父类
public Student() {
super(); //此时写不写此语句效果相同
System.out.println("一个新的Student实例化对象产生了");
}
}
public class Demo { //主类
public static void main(String[] args) {
new Student(); //子类对象实例化流程,会自动实现父类的实例化****
}
}
- super():表示的就是子类调用父类构造的句子,该语句只能放在子类构造方法的首行。在默认情况下,子类只会调用父类中的无参构造方法,所以写不写super()区别不大,但如果说父类里面没有提供无参构造,这是就必须利用super()来明确调用有参构造
class Person { //定义一个类,父类
private String name;
private int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
class Student extends Person { //studet是子类*****
public Student(String name,int age){ //构造方法
super(name,age); //明确调用父类构造
}
}
方法覆写
- 方法覆写:当子类定义了与父类方法名称相同,参数类型即个数完全相同(跟父类一模一样)的时候,就称为方法覆写
- 方法覆写的意义在于:优化父类的功能
class Channel {
public void connect() {
System.out.println("【父类】进行资源的连接");
}
}
class DatabaseChannel extends Channel {
public void connect() { //保留子类已有的方法名称,而后进行覆写**
super.connect(); //直接调用父类中的方法
System.out.println("【子类】进行资源库数据的连接");
}
}
public class Demo {
public static void main(String[] args) {
DatabaseChannel channel = new DatabaseChannel();
channel.connect();
}
}
- 由于此处实例化的是子类(DatabaseChannel)对象,所以对此调用的方法一定是被子类覆写过的方法,如果该方法没有被覆写,那么将调用父类中提供的方法。
- 在子类中进行父类方法的调用的时候,一定要加上super.方法()
final关键字
- 使用final定义的类不能被继承
final class Channel{ //该类无法被继承,不能有子类了
}
- 定义不能被覆写的方法
class Channel{
pubilc final void connect(){} //该方法不能被覆写了
}
- 定义不可变的常量
class Channel{
private final int ON = 0; //ON就是常量
private final int OFF = 1; //OFF就是常量
}
- 定义全局常量
多态性
- 方法多态性
(1)方法的重载:方法名称相同,但是参数个数不同,类型不同或多类型的顺序不同。
(2)方法的覆写:当子类定义了与父类方法名称相同,参数类型即个数完全相同(跟父类一模一样)的时候,就称为方法覆写 - 对象多态性:父子实例之间的转换处理,有两种模式
向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。
向下转型:父类引用的对象转换为子类类型称为向下转型。
(1)对象向上转型:父类名 父类对象名=new 子类对象()(自动完成转换)
class Message {
public void print() {
System.out.println("www.mldn.cn");
}
}
class DatabaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息");
}
}
public class Demo {
public static void main(String[] args) {
Message msg = new DatabaseMessage(); //向上转型***
msg.print();
}
}
- 向上转型的优势:可以对参数进行统一的设计。(提高程序的可维护性)
class Message {
public void print() {
System.out.println("www.mldn.cn");
}
}
class DatabaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息");
}
}
class WebServerMessage extends Message {
public void print() {
System.out.println("WEB服务器连接信息");
}
}
public class Demo {
public static void main(String[] args) {
fun(new WebServerMessage() ); // Message msg = new DatabaseMessage(); //向上转型
fun(new DatabaseMessage() ); // Message msg = new WebServerMessage() ;
}
public static void fun(Message msg){ //不管传递的是那个子类,都可以接收
msg.print();
}
}
(2)对象向下转型:子类类型名 变量名 = (子类类型名)之前的变量名(强制完成转换)
class Person{
public void print(){
System.out.println("一个正常人的行为");
}
}
class Superman extends Person { //类的继承
public String fly(){
return "我会飞";
}
public String fire(){
return "我会喷火";
}
}
public class Demo {
public static void main(String[] args) {
System.out.println("正常状态下超人是一个普通人");
Person per =new Superman(); //向上转型
per.print();
System.out.println("外星人骚扰地球");
Superman man =(Superman) per; //向下转型
System.out.println(man.fly()); //调用子类功能
System.out.println(man.fire());
}
}
注意:在进行向下转型之前一定要进行向上转型
instanceof(关键字)
- 为了保证向下转型的正确行,往往需要先使用instanceof关键字进行判断
- 语法:对象 instanceof 类(返回boolean类型,如果是true,表示实例是指定类对象)
class Person{
public void print(){
System.out.println("一个正常人的行为");
}
}
class Superman extends Person { //类的继承
public String fly(){
return "我会飞";
}
public String fire(){
return "我会喷火";
}
}
public class Demo {
public static void main(String[] args) {
Person per =new Person(); //未转型
System.out.println(per instanceof Person); //true
System.out.println(per instanceof Superman); //flase
}
}
class Person{
public void print(){
System.out.println("一个正常人的行为");
}
}
class Superman extends Person { //类的继承
public String fly(){
return "我会飞";
}
public String fire(){
return "我会喷火";
}
}
public class Demo {
public static void main(String[] args) {
Person per =new Superman(); //向上转型
System.out.println(per instanceof Person); //true
System.out.println(per instanceof Superman); //true
}
}
- instanceof的使用
class Person{
public void print(){
System.out.println("一个正常人的行为");
}
}
class Superman extends Person { //类的继承
public String fly(){
return "我会飞";
}
public String fire(){
return "我会喷火";
}
}
public class Demo {
public static void main(String[] args) {
Person per =new Superman(); //向上转型
if(per instanceof Superman){ //判断是否进行了向上转型
Superman man =(Superman) per; //向下转型
System.out.println(man.fly()); //调用子类功能
System.out.println(man.fire());
}
}
}
Java四种访问修饰符作用范围
访问权限 | 本类 | 本包 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | x |
default | √ | √ | x | x |
private | √ | x | x | x |