面对对象
OPP
面对对象思想
public class oop_03 {
public static void main(String[] args){
创建一个 student 对象:
student stu =new student();
给 成员变量赋值:
stu.name="tom";
stu.age=18;
System.out.println(stu.name+":"+stu.age);
调用 成员方法:
stu.eat();
stu.sleep(10);
System.out.println(stu.talk(stu.name));
}
}
创建一个类:
class student{
创建 成员变量
String name;
int age;
创建 成员方法:
public void eat(){
System.out.println("吃...");
}
public void sleep(int number){
System.out.println("睡 "+number);
}
public String talk(String who){
return "和"+who+"说话";
}
}
方法的重载
一、方法重载的定义:
在同一个类中,允许存在一个以上的同名方法,形参列表不一致即可。
总结: “两同一不同”:
同一个类、相同方法名
参数列表不同:参数个数不同,参数类型不同
二、如何判断是否构成方法的重载?
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没关系!
可变形参 args
args 的基本格式
public void args(String... str){
System.out.println(1);
}
注意事项
1、可变参数不能与 数组产生重载 两者不能共存
/* public void args(String[] num){ //错误写法
System.out.println(2);
}*/
2.可变形参要写到形参的最后
public void args(String a,String...b){ //正确
}
/* public void args(String...b,String a){ //错误写法
}*/
递归的调用
定义:一个方法内自己调用自己本身 称为递归
public class OOP_04 {
public static void main(String[] args) {
//求1到100之间的和
方式1 循环实现
int sum=0;
for (int i = 0; i <=100; i++) {
sum+=i;
}
System.out.println(sum);
OOP_04 text =new OOP_04();
System.out.println(text.getsum(100));
}
方式2 递归实现
public int getsum(int a ){
if (a==1){
return 1;
}else{
return a+getsum(a-1);
}
}
}
封装
封装总结:
//四种权限修饰符 (小到大排序) private 缺省 protected public
// 修饰符 类内部 同一个包 不同包的子类 同一个工程
// private yes
// 缺省 yes yes
// protected yes yes yes
// public yes yes yes yes
public class OOP_04 {
public static void main(String[] args) {
person per = new person();
per.name="tom";
加了 private 关键字 不能直接调用
per.age 错误写法
正确写法
per.setAge(18); //不能直接调用 通过 setAge调用
System.out.println(per.getAge()); //获取
}
}
封装 private
class person{
成员变量
String name;
private int age; //加了 private 不能直接调用
String sex;
成员变量的封装和体现: public 提供了 getXxx 和 setXxx 的方法
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age;
}
//成员方法
public void eat(){
System.out.println("吃...");
}
}
构造器
构造器的作用:
1、创建对象
2、创建对象完成初始化
//说明:
//当显示的定义的构造器,系统就不会提供给我们默认的了;
public class text {
public static void main(String[] args){
person1 per =new person1(); //会执行构造器里面的东西
//有钟初始化的意思;
person1 per1 =new person1("tom",18);
person1 per2 =new person1("jak");
}
}
class person1{
//创建成员变量
private String name;
int age;
public boolean sex;
//创建构造器
public person1(){
System.out.println("构造器....");
}
public person1(String name){
//调用 persong1 构造器
this();
this.name=name;
System.out.println("构造器1..."+this.name+","+this.age);
}
public person1(String name,int age ){
// this(name);
this(); //必须声明在当前构造器的首行;且只能声明一个
}
//创建方法
public void eat(){
System.out.println("吃...");
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
}
package 和 import 作用
------------------------------------
关键字的使用
1、每一个 ”.“ 代表一层文件的目录
2、包,属于标识符,遵循标识符的命名规则
补充:JDK中的主要包介绍:
-----------------------------------
import:导入
* 1. 在源文件中显式的使用import结构导入指定包下的类、接口
* 2. 声明在包的声明和类的声明之间
* 3. 如果需要导入多个结构,则并列写出即可
* 4. 可以使用"xxx.*"的方式,表示可以导入xxx包下的所结构
* 5. 如果使用的类或接口是java.lang包下定义的,则可以省略import结构
* 6. 如果使用的类或接口是本包下定义的,则可以省略import结构
* 7. 如果在源文件中,使用了不同包下的同名的类,则必须至少一个类需要以全类名的方式显示。
* 8. 使用"xxx.*"方式表明可以调用xxx包下的所结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
*
* 9. import static:导入指定类或接口中的静态结构:属性或方法。
import java.util.*; //等价 import java.util.Scanner;
import static java.lang.System.*; // 输出可以写省 System
public class package_import_text_05 {
public static void main(String[] args){
new Scanner(System.in).next();
out.println("tom...."); //导入了包之后可以省略写 System
}
}
常用的快捷键
常用快捷键:
alt + / alt + enter 补全代码的声明
ctrl +1 快速修复
ctrl + shift +o 批量导包
Ctrl+] 诸如{}围起来的代码块,使用该快捷键可以快速跳转至代码块的结尾处
Ctrl+[ 同上,快速跳至代码块的开始出
Ctrl+Shift+Enter 将输入的if、for、函数等等补上{}或者;使代码语句完整
Ctrl+Delete 删除光标所在至单词结尾处的所有字符
Ctrl+BackSpace 删除光标所在至单词开头的所有字符
Ctrl+向左箭头 将光标移至前一个单词
Ctrl+向右箭头 将光标移至后一个单词
Ctrl+向上箭头 向上滚动一行
Ctrl+向下箭头 向下滚动一行
Ctrl+W 选中整个单词
Ctrl+Shift+U 切换大小写
继承
子类和父类的体现
一、定义一个父类
//定义一个父类
public class person {
String name;
int age;
public void eat(){
System.out.println("人要吃....");
}
}
二、定义一个子类来继承父类
student 为子类、超类、基类、superclass
person 为父类 、派生类、subclass
public class student extends person {
String sex;
public void sleep(){
System.out.println("人要睡觉....");
}
}
三、创建一个对象来调用
public class extend_01 {
public static void main(String[] args) {
student stu =new student();
通过子类可以调用父类里面的方法 属性等...
stu.eat();
stu.sleep();
}
}
方法的重写
一、创建一个父类person
public class person {
public void eat(){
System.out.println("人也要多吃饭...");
}
public void eat(String name){
System.out.println(name +"人也要多吃饭...");
}
}
二、创建一个子类student 来继承父类的person 并进行重写
public class student extends person{
子类继承了父类后 对方法的重写 子类对象实例化 会调用子类中的方法...
public void eat(){
System.out.println("学生要吃饭...");
}
public void eat(String name){
System.out.println(name+"学生要吃饭...");
}
}
三、创建一个子类对象实例化
方法的重写:
定义:子类继承了父类以后,可以对父类中同名同参数的方法进行覆盖操作
重写的规定:
1、子类中的方法名、形参列表和父类中的方法名、形参列表 相同
2、子类方法中的权限修饰符不小于父类方法中的权限修饰符
>特殊情况:子类不能重写父类中 peivate中的方法...
3、返回值类型:
>父类中方法返回值的类型是 void,则子类子类重写的方法的返回值类型也只能是 void
>父类中方法返回值的类型是 A类型,则子类子类重写的方法的返回值类型可以是A类或A类的子类
>父类中方法返回值的类型是 基本数据类型,则子类子类重写的方法的返回值类型必须是相同的基本数据类型
4、补充:子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常
public class overwrite {
public static void main(String[] args) {
student p =new student();
p.eat(); //调用子类中的方法
p.eat("tom.."); //调用子类中的方法
}
}
super关键字的使用
一、声明一个父类 person
public class person{
int id=100;
String name;
int age;
public person(){
}
public person(String name,int age){
System.out.println("父类构造器....");
}
public void eat(){
System.out.println("人:要吃饭...");
}
public void sleep(){
System.out.println("人:要睡觉...");
}
}
二、声明一个子类 student
public class student extends person{
String sex;
int id=111;
public student(){
会默认的调用 父类的空参
super();
}
public student(String sex){
会默认的调用 父类的空参
super();
调用父类的构造器 调用构造器 必须放在首行
super("tom",18);
}
public void eat(){
System.out.println("学生:要吃饭...");
}
public void show(){
this 会在子类中找 没找到在去父类中找
super 会直接去夫父类中找
System.out.println(this.id+"、" + super.id);
eat(); 方法重写默认使用本类中的方法
super.eat(); 直接去调用父类中的方法
}
}
三、super关键字的对象
super关键字的使用
super.属性 super.方法 super(形参列表) //调用构造器
1、super可以用来调用:父类的属性 、父类的方法、父类的构造器
2、方法被重写时、属性相同时 我们可以显示的使用
this 、 super 灵活的调用父类和子类中的方法 和属性、构造器
public class supertest {
public static void main(String[] args) {
student stu =new student(); 会默认的调用super();
stu.show();
调用父类的构造器
student stu1 =new student("dd");
}
}
多态
上下转型
package 多态;
public class 向上转型 {
private static Object animal;
public static void main(String[] args) {
// 向上转型
animal aa=new cat();
// 猫猫在叫唤
aa.cry();
// 可以调用父类中所有的成员(需要遵守访问权限)
// 不可以调用子类特有的成员
// 错误: aa.sleep();
// 向下转型:
cat bb=(cat)aa;
bb.sleep();
}
}
多态属性问题
package 多态;
public class 多态属性的问题 {
public static void main(String[] args) {
// 向上转型
A a=new B();
// 属性看编译类型
System.out.println(a.count); //10
// 向下转型
B b=(B)a;
// 看编译类型
System.out.println(b.count); //20
}
}
class A{
int count=10;
}
class B extends A {
int count=20;
}
判断是否是他的运行类型
package 多态;
public class 判断是不是它的运行类型 {
public static void main(String[] args) {
// 判断是不是它的运行类型
BB bb = new BB();
AA aa=new BB();
System.out.println(bb instanceof AA); //true
System.out.println(aa instanceof AA ); //true
System.out.println(bb instanceof BB); //true
System.out.println(aa instanceof BB); //true
Object obj =new Object();
System.out.println(obj instanceof BB ); //false
}
}
class AA{
}
class BB extends AA{
}
多态动态绑定机制
package 多态.动态绑定机制;
public class text{
public static void main(String[] args) {
// java 的动态的绑定机制
// 当调用对象的绑定机制的时候,该方法会和该对象的内存地址/运行地址绑定
// 当调用对象的属性的时候 ,没有动态绑定机制 ,哪里调用,哪里使用
// 编译类型 AA 运行类型 BB
// 向上转型
AA a=new BB();
System.out.println(a.sum()); //30
System.out.println(a.sum1()); //
}
}
class AA {
public int i=10;
public int sum(){
return geti() +10;
}
public int sum1(){
return i+10;
}
public int geti(){
return i;
}
}
class BB extends AA {
// public int i = 20;
// public int sum(){
// return i+20;
// }
public int geti(){
return i;
}
public int sum1(){
return i+10;
}
}