J3 java面向对象
作者:互联网
1.方法进阶
1.1方法定义
- 基本同C差不多,只是在方法类型之前多了修饰符如public,private等
- 返回值同C一样,有啥返回值就定义啥类型方法
1.2方法重载
- 从此处开始方法将与C存在较大差别
- 重载定义:方法名相同,但是参数的类型和个数不同,通过传递参数的个数和类型不同来完成不同功能(区分不同方法)
- 例如,同样的方法名,不同的参数类型与个数构成重载
public class demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
tell("Tom", 2, 3);
tell("Tik", 1, 2, 3);
}
public static void tell(String name, int i, int j){
System.out.println(name + (i + j));
}
public static void tell(String name, int i, int j, int k){
System.out.println(name + (i+j+k));
}
}
- 注意,如果方法返回值不同,则不可构成方法重载,例如
public class demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
tell("Tom", 2, 3);
tell("Tik", 1, 2, 3);
}
public static void tell(String name, int i, int j){
System.out.println(name + (i + j));
}
// 此处函数返回值不同,不构成重载!!!!!!!!!!!!!!!!!!!!!
// public int tell(){
//
// }
// public String tell(){
//
// }
}
- 构造方法也可以构成重载,例如
package com.hanqi.demo1;
class SmallPerson{
private int age;
private String name;
private int id;
public SmallPerson(int age, String name, int id) {
this.age = age;
this.name =name;
this.setId(id);
}
public SmallPerson(String name, int id) {
this.age = 20;
this.name =name;
this.setId(id);
}
public SmallPerson(int id) {
this.age = 30;
this.name = "王大锤";
this.setId(id);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
public class test06 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
SmallPerson s = new SmallPerson(21, "hq", 4009);
System.out.println(s.getId()+s.getName()+s.getAge());
SmallPerson s1 = new SmallPerson("wahaha", 4008);
System.out.println(s1.getId()+s1.getName()+s1.getAge());
SmallPerson s2 = new SmallPerson(4007);
System.out.println(s2.getId()+s2.getName()+s2.getAge());
}
}
//////
4009hq21
4008wahaha20
4007王大锤30
1.3方法重写
- 在继承中存在重写的概念,即子类定义了和父类同名的方法
- 方法名称相同,返回类型相同,参数相同
- 重写限制
1.被子类重写的方法不能拥有比父类方法更加严格的访问权限
2.访问权限:private<default<public
3.一半子类与父类方法权限设置为相同即可
- 示例,在示例中子类B继承自父类,其重写了tell方法,在最后调用的时候会显示重写之后的方法
package com.hanqi.demo1;
class A{
public void tell() {
System.out.println("我是tell方法");
}
}
class B{
public void tell() {
System.out.println("重写了tell方法");
}
}
public class test05 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
B b = new B();
b.tell();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
重写了tell方法
- 要想显示重写之前的方法,需要使用
super
关键字,如下
package com.hanqi.demo1;
class A{
public void tell() {
System.out.println("我是tell方法");
}
}
class B extends A{
public void tell() {
super.tell();
System.out.println("重写了tell方法");
}
}
public class test05 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
B b = new B();
b.tell();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
我是tell方法
重写了tell方法
1.4super关键字
super
关键字强行调用父类的方法执行super
不一定在重写中使用,也可以表示那些方法时从父类继承而来- 继承中的构造方法
- 在构造子类的过程中必须调用其父类的构造方法
- 子类可以在自己的构造方法中使用
super(argument_list)
调用父类的构造方法,使用this(argument_list)
调用本类的构造方法,如果调用super必须写在子类构造方法的第一行- 如果子类的构造方法中没有显示地调用父类构造方法,则系统默认调用父类的无参构造方法
- 如果子类构造方法中既没有显示地调用父类构造方法,而父类中又没有无参的构造方法,则编译错误
- 如以下例子,类BB继承自类AA,并重写了AA中的f方法。在new一个BB类的时候会默认调用父类的无参构造方法,之后再调用自己的构造方法,最后调用重写的方法
package com.hanqi.demo1; class AA{ protected void print(String s) { System.out.println(s); } AA(){ print("调用父类A的无参构造方法"); } public void f() { print("调用A的f()方法"); } } class BB extends AA{ BB(){ print("调用子类B的无参构造方法"); } public void f() { print("调用B的f()方法"); } } public class test07 { public static void main(String[] args) { BB b = new BB(); b.f(); } } /////////////////////////// 调用父类A的无参构造方法 调用子类B的无参构造方法 调用B的f()方法
2.类
2.1类的声明
- 类的声明方式
class 类名称{
类属性;
类方法;
}
- 声明一个类需要通过一个关键字
class
- 例如
package com.hanqi.classdemo;
class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+"\n年龄"+age);
}
}
public class classDemo1 {
public static void main(String[] args) {
Person zhangSan = null; //声明一个对象
zhangSan = new Person(); //为对象分配空间(实例化操作)
// Person zhangSan = new Person();
}
}
3.对象
3.1类与对象的关系
- 类是某一类事物的描述,是抽象的,概念上的意义;而对象是实际存在的该类事物的某个个体,又称为类的实例
- 例如,动物是一个类,猫狗等则为动物的一个对象
3.2对象的创建
- 直接
new
即可 Person zhangSan = new Person();
3.3对象内存分配
- 在没有
new
之前,即只写了Person zhangSan = null;
,此时的对象还仅仅是一个栈内的变量(类似C中定义一个指针,指针还未指向任何内存空间) - 当执行
new
之后,JVM将从堆空间中开辟内存用来保存zhangSan对象的详细信息(new相当于C中的malloc) - 之后zhangSan指向堆内分配的空间,默认初始化为0或者null
- 完整代码
package com.hanqi.classdemo;
class Person{
String name;
int age;
public void tell(){
System.out.println("姓名:"+name+"\n年龄:"+age);
}
}
public class classDemo1 {
public static void main(String[] args) {
// Person zhangSan = null; //声明一个对象
// zhangSan = new Person(); //为对象分配空间(实例化操作)
Person zhangSan = new Person();
zhangSan.name = "张三"; //对象赋值
zhangSan.age = 80;
zhangSan.tell();
}
}
- 执行结果
姓名:张三
年龄:80
- 如果没有执行
new
操作则会报错,错误为空指针异常
Exception in thread "main" java.lang.NullPointerException at com.hanqi.classdemo.classDemo1.main(classDemo1.java:16)
- 因为创建对象默认为null,在之后执行访问操作的时候会非法访问,类似C语言中的
null.a;null.b
,必然会报错]\
4.面向对象三大特性
4.1封装
- 目的:保护某些属性和方法不被外部看见
- 实现:为属性和方法进行封装是通过关键字private声明的
- 既然不能为外部所访问,那么该如何修改类中元素呢?系统提供了接口函数,即我们需要实现该属性的
set
和get
方法,让这些私有属性被外部访问 - 示例
package com.hanqi.classdemo;
class Person1{
private int age;
private String name;
public int getAge(){
return age;
}
public void setAge(int age){
if(age>=0 && age <=200){ //不满足该条件,则赋值操作无法进行
this.age = age;
}
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public void tell(){
System.out.println("年龄:"+getAge()+"\n姓名:"+getName());
}
}
public class classDemo2 {
public static void main(String[] args) {
Person1 per = new Person1();
per.setAge(-80); //非法赋值,赋值无法完成
per.setAge(80);
per.setName("张三");
per.tell();
}
}
4.2多态
- 扩展类功能
4.3继承
4.3.1概念
- 继承是为了扩展父类的功能
- java中使用
extends
关键字完成继承 - 方法重载
- 对象的多态性
4.3.2格式
- 继承范式如下
class 子类 extends 父类{
}
- 示例,此处Student类继承Person类中的部分方法,而且实现了属于自己的方法与变量
package com.hanqi.demo1;
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student extends Person{
// private int age;
// private String Name;
private int score;
// public int getAge() {
// return age;
// }
// public void setAge(int age) {
// this.age = age;
// }
// public String getName() {
// return Name;
// }
// public void setName(String name) {
// Name = name;
// }
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public void tell() {
System.out.println("姓名:"+getName()+"\n年龄:"+getAge());
}
public void tell1() {
System.out.println("\n成绩:"+getScore());
}
}
public class test02 {
public static void main(String[] args) {
Student s = new Student();
s.setAge(20);
s.setName("王八");
s.setScore(100);
s.tell();
s.tell1();
}
}
4.3.3继承限制
- 在java中只允许单继承(一个儿子只能有一个爸爸)
- 子类不能直接访问父类的私有成员,但是可通过get,set方法访问
- 示例
package com.hanqi.demo1;
class People1{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Worker extends People1{
public void tell() {
System.out.println("年龄:"+getAge());
}
}
class PetWorker extends Worker{
}
public class test03 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Worker w = new Worker();
w.setAge(100);
w.tell();
}
}
5.匿名对象
5.1概念
- 匿名对象就是没有名字的对象,如果程序中只是用一次该对象,就可以使用匿名对象的方式
5.2举例
package com.hanqi.classdemo;
class Student{
public void tell(){
System.out.println("makabaka");
}
}
public class classDemo3 {
public static void main(String[] args) {
// Student stu = new Student();
// stu.tell();
new Student().tell(); //匿名对象,只使用一次
}
}
6.构造方法
6.1格式
- 相较于普通方法,构造方法没有返回类型
访问修饰符 类名称(){
程序语句;
}
- 构造方法的方法名与类名相同
- 构造方法在new时候会自动调用
- 构造方法主要是为类中的属性初始化
- 每个类在实例化之后都会调用构造方法,如果没有构造方法,程序在编译的时候会创建一个无参的什么都不做的构造方法
- 构造方法也可以重载
6.2举例
- 不传参
package com.hanqi.classdemo;
class People{
//创建构造方法
public People(){
System.out.println("执行构造方法");
}
}
public class classDemo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
People hanqi = new People();
}
}
- 传参
package com.hanqi.demo1;
class People{
int age;
String name;
public People(int age, String name) {
this.age = age;
this.name = name;
System.out.println("姓名:"+name+"\n年龄:"+age);
}
}
public class test01 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
People per = new People(28, "王大翠");
}
}
- 构造方法重载
package com.hanqi.demo1;
class People{
int age;
String name;
public People(int age, String name) {
this.age = age;
this.name = name;
System.out.println("姓名:"+name+"\n年龄:"+age);
}
public People(int age) {
this.age = age;
System.out.println("年龄:"+age);
}
}
public class test01 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
People per = new People(28);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
年龄:28
7.子类对象实例化
7.1注意
- 在子类对象实例化之前,必须先调用父类的构造方法,之后调用子类的构造方法(先有老子后有儿子)
- 此处在子类中并没有调用父类构造方法,但实际父类构造方法却执行了,因为编译器默认在子类的构造方法中加入了super关键字
- 示例
package com.hanqi.demo1;
class Father{
private int age;
private String name;
public Father() {
System.out.println("父类构造方法");
}
}
class Son extends Father{
public Son() {
System.out.println("子类构造方法");
}
}
public class test04 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Son s = new Son();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
父类构造方法
子类构造方法
标签:java,name,构造方法,int,age,J3,面向对象,void,public 来源: https://www.cnblogs.com/Meiyangyang945/p/15106558.html